Coded UI test takes 2-3 minutes to pass - vb.net

So I am working with Coded UI to run some automated tests and one of the tests takes an extremely long time to complete.
I used breakpoints and found that after End Get in the bottom block of code, nothing happens for minutes and then finally the Assert.AreEqual completes and the test passes.
I tried changing a few playback settings but nothing changed. Does anyone know what is going on, and how I can fix it?
-The first block of code is a generated Assert method that gets called by the test
-The second block of code is called in the Assert parameters
'''<summary>
'''assert_clicked_columnhead_requestor - Use 'assert_clicked_columnhead_requestorExpectedValues' to pass parameters into this method.
'''</summary>
Public Sub assert_clicked_columnhead_requestor()
Dim uINameCell As HtmlCell = Me.UIAppWindow1.UIAppDocument.UIX978532666mkrdataTblTable1.UINameCell
'Verify that 'Name' cell's property 'InnerText' equals 'Name'
Assert.AreEqual(Me.assert_clicked_columnhead_requestorExpectedValues.UINameCellInnerText, uINameCell.InnerText)
End Sub
Public Overridable ReadOnly Property assert_clicked_columnhead_requestorExpectedValues() As assert_clicked_columnhead_requestorExpectedValues
Get
If (Me.massert_clicked_columnhead_requestorExpectedValues Is Nothing) Then
Me.massert_clicked_columnhead_requestorExpectedValues = New assert_clicked_columnhead_requestorExpectedValues()
End If
Return Me.massert_clicked_columnhead_requestorExpectedValues 'PROBLEM HERE
End Get
End Property
As requested
'''<summary>
'''click_columnhead_requestor
'''</summary>
Public Sub click_columnhead_requestor()
Dim uIRequestorCell As HtmlHeaderCell = Me.UIAppWindow1.UIAppDocument.UIRequestorCell
'Click 'Requestor' cell
Mouse.Click(uIRequestorCell, New Point(51, 23))
End Sub
Public ReadOnly Property UIAppWindow1() As UIAppWindow1
Get
If (Me.mUIAppWindow1 Is Nothing) Then
Me.mUIAppWindow1 = New UIAppWindow1()
End If
Return Me.mUIAppWindow1
End Get
End Property
Public ReadOnly Property UIX978532666mkrdataTblTable1() As UIX978532666mkrdataTblTable1
Get
If (Me.mUIX978532666mkrdataTblTable1 Is Nothing) Then
Me.mUIX978532666mkrdataTblTable1 = New UIX978532666mkrdataTblTable1(Me)
End If
Return Me.mUIX978532666mkrdataTblTable1
End Get
End Property

Coded UI does searches for precisely what is given in the search and filter properties, that operates quite fast. However, if that search fails then Coded UI does a smart match trying to find something similar and that can take a long time. It is necessary because titles etc can change a little from run to run. Changing the tests to avoid needing a smart match can dramatically improve the search speed. The general approach is to modify the search from equality to contains and to remove the part of the string that changes. A Microsoft blog explains in more detail, see http://blogs.msdn.com/b/dave_froslie/archive/2012/08/10/why-do-my-coded-ui-tests-pause-during-playback.aspx

¿? have you tried changing the value of ..
Playback.PlaybackSettings.SearchTimeout = miliseconds;
msdn playbacksettings.searchtimeout
good luck and tell us something

Related

VBA Settings Dialog using MVP - do I need a model?

I've been reading up on many examples of MVP (Model-View-Presenter) and their variations (Passive view, Supervising view) to try and make my solutions more robust (and reusable) in VBA (using Excel as the host in this instance). The problem I've found is finding good, simple examples in VBA that are not complete overkill for the (hopefully) simple examples I need.
I'm attempting to create a "settings" dialogue that stores certain configuration in a worksheet (this is my "repository").
Here's my main procedure, triggered by the user:
Private Sub ShowImportSelector()
Dim importPresenter As DataImportPresenter
Set importPresenter = New DataImportPresenter
importPresenter.LoadConfig
If importPresenter.Show = -1 Then Exit Sub
importPresenter.SaveConfig
' begin processing...
If (CStr([Settings.SelectedVersion].Value2) = "QQ") Then
' ...
End If
End Sub
Here is my "presenter" (here I use range names for the source, and config destination):
Option Explicit
Private m_importForm As FImport
Private Sub Class_Initialize()
Set m_importForm = New FImport
End Sub
Public Sub LoadConfig()
m_importForm.SetAvailableVersions "tblVERSION"
m_importForm.SetAvailableSalesOrgs "tblSALESORG"
m_importForm.SetAvailableCategories "tblCATEGORY"
m_importForm.ToolName = "Forecast"
End Sub
Public Sub SaveConfig()
[Settings.SelectedVersion].Value2 = m_importForm.SelectedVersion
[Settings.SelectedSalesOrg].Value2 = m_importForm.SelectedSalesOrg
[Settings.SelectedCategory].Value2 = m_importForm.SelectedCategory
End Sub
Public Function Show() As Integer
m_importForm.Show vbModal
Show = m_importForm.Result
End Function
And now the "View" (a VBA Form):
Option Explicit
Private m_selectedVersion As String
Private m_selectedSalesOrg As String
Private m_selectedCategory As String
Private m_toolName As String
Private m_dialogueResult As Long
Public Property Get ToolName() As String
ToolName = m_toolName
End Property
Public Property Let ToolName(ByVal value As String)
m_toolName = value
ToolNameLabel.Caption = value
End Property
Public Property Get Result() As Long
Result = m_dialogueResult
End Property
Public Property Get SelectedVersion() As String
SelectedVersion = m_selectedVersion
End Property
Public Property Get SelectedSalesOrg() As String
SelectedSalesOrg = m_selectedSalesOrg
End Property
Public Property Get SelectedCategory() As String
SelectedCategory = m_selectedCategory
End Property
Public Sub SetAvailableVersions(ByVal value As String)
VersionSelector.RowSource = value
End Sub
Public Sub SetAvailableSalesOrgs(ByVal value As String)
SalesOrgSelector.RowSource = value
End Sub
Public Sub SetAvailableCategories(ByVal value As String)
CategorySelector.RowSource = value
End Sub
Private Sub SaveSelections()
m_selectedVersion = VersionSelector.value
m_selectedSalesOrg = SalesOrgSelector.value
m_selectedCategory = CategorySelector.value
End Sub
Private Sub CloseButton_Click()
m_dialogueResult = -1
Me.Hide
End Sub
Private Sub ImportButton_Click()
SaveSelections
m_dialogueResult = 0
Me.Hide
End Sub
At this point, I have become confused with the possible directions I could go in terms of adding a model to the above - question is: is this even needed for this simple example?
MVP architecture makes cleaner code, but cleaner code isn't the primary purpose of MVP; achieving loose coupling, higher cohesion, and testability is.
If loosely-coupled components and unit-testable logic isn't a requirement, then full-blown MVP is indeed overkill, and having the "model" exposed as properties on the "view" is definitely good enough, as it already helps making your "presenter" not need to care about form controls. You're treating the form as the object it's begging to be, and pragmatically speaking this could very well be all you need. I'd make the Show method return an explicit Boolean though, since it's implicitly used as such.
On the other hand, if you are shooting for decoupling and testability, then extracting the model from the view would only be step one: then you need to decouple the presenter from the worksheet, and maybe introduce some ISettingsAdapter interface that abstracts it away, such that if/when the configuration needs to go to a database or some .config file, your presenter code doesn't need to change in any way... but this requires designing the interfaces without having any particular specific implementation in mind, i.e. something that works without changes regardless of whether the data is on a worksheet, in some flat file, or in some database table.
MVP demands a paradigm shift: MVP isn't procedural programming anymore, it's OOP. Whether OOP is overkill for your needs depends on how much coupling you're willing to live with, and how frail this coupling is making your code in the face of future changes. Often, abstraction is enough: using named ranges instead of hard-coded range addresses is one way of improving the abstraction level; hiding the worksheet behind an adapter interface implemented by a worksheet proxy class (whatever you do, never make a worksheet module implement an interface: it will crash) is another - depends where your threshold for "overkill" is, but if you do achieve full decoupling and write the unit tests, nobody can blame you for going overboard: you're just following the industry best-practices that every programmer strives for, improving your skills, and making it much easier to later take that code and rewrite it in .NET, be it VB or C#. I doubt anyone would argue that full-blown MVP is overkill in .NET/WinForms.

Loading My.Settings in other solution

I need to load My.settings from the first Solution into the Second.
In the first project I have a helper class for getting the Settings.
Public Class format
Public NotInheritable Class Helper
Private Sub New()
End Sub
Public Shared Function getAppSetting() As String
Dim returnValue As Object = My.Settings.format
If returnValue Is Nothing Then
Return String.Empty
Else
Return returnValue.ToString
End If
End Function
Public Shared Function getAppSettingTheme() As String
Dim returnValue_theme As Object = My.Settings.theme_selected
If returnValue_theme Is Nothing Then
Return String.Empty
Else
Return returnValue_theme.ToString
End If
End Function
End Class
End Class
This class I have implemented in the other Solutions (Even addiction I have a set)
In other Solutions I have the code for getting the Settings.
Imports MyProject.format.Helper
MsgBox(getAppSettingTheme())
But in the MsgBox I see Default Settings (Unchanged) While in the first solution displays the user-changed settings.
My.Settings I have saved [My.settings.save]
If you choose to do this in a complicated way,what you have to do is,make classes in the first project to read My.Settings,then reference the project in the other project and use it...
However,i'll rather describe an easier way(tho the above one is not that hard) to achieve your goal.
Firstly,i believe that you are using My.Settings to store some data,right ?If so,you can simply save the data to a text file and read it from anywhere you want.This will save plenty of your code and make it tidy :)
As you seem to be a beginner,i would try to keep it as simple as possible and explain in the simplest words...
Now,let's assume,you have 4 My.Settings entries as follows :
UserName
Password
Phone
Age
Instead of writing this data in My.Settings,write it to a text file.Let's assume a user inputs relevant data and it looks somewhat like this :
Zack Rayan
1212121
+090990809809
20
To write a text file, you can simply use File.WriteAllText but as we see that here,our data is in multiline,we can make use of the following :
FIle.WriteAllLines
File.AppendText
Well,let's use File.AppendText method(you can use the below code with WriteAllText as well :)) :
File.AppendText("C:\test.mycustomExtension" , "Zack Rayan" + Environment.NewLine + "1212121" + Environment.NewLine + "+090990809809" + Environment.NewLine + "20")
This will write a text file for you containing the given data in separate lines as well as you will have your own custom extension for the file :)
Now,how to use it ?
Simple :
Dim ReadFile as New List(Of String)(File.ReadAllLines("C:\Test.mycustomextension"))
Now,let's assume,when you were using My.Settings, you used some codes like this :
If My.Settings.UserName = "Zack" Then
......
Scroll up and look closely.UserName was your first entry in My.Settings and when we wrote the text file,ZACK RAYAN-the assumed username was also written in the first line
A few lines above, i created a list which reads the text file.It needs no saying that it will read(and store) the first line first and then move on gradually. So,where you used :
If My.Settings.UserName = "Zack" Then
u should now use :
If ReadFile(0) = "Zack" Then
I hope this helps to enrich your knowledge :)

ByRef Local Variable using Linq

I'm having trouble with selecting only part of a collection and passing it by reference.
So I have a custom class EntityCollection which is , who guessed, a collection of entities. I have to send these entities over HTTPSOAP to a webservice.
Sadly my collection is really big, let's say 10000000 entities, which throws me an HTTP error telling me that my request contains too much data.
The method I am sending it to takes a Reference of the collection so it can further complete the missing information that is autogenerated upon creation of an entity.
My initial solution:
For i As Integer = 0 To ecCreate.Count - 1 Step batchsize
Dim batch As EntityCollection = ecCreate.ToList().GetRange(i, Math.Min(batchsize, ecCreate.Count - i)).ToEntityCollection()
Q.Log.Write(SysEnums.LogLevelEnum.LogInformation, "SYNC KLA", "Creating " & String.Join(", ", batch.Select(Of String)(Function(e) e("nr_inca")).ToArray()))
Client.CreateMultiple(batch)
Next
ecCreate being an EntityCollection.
What I forgot was that using ToList() and ToEntityCollection() (which I wrote) it creates a new instance...
At least ToEntityCollection() does, idk about LINQ's ToList()...
<Extension()>
Public Function ToEntityCollection(ByVal source As IEnumerable(Of Entity)) As EntityCollection
Dim ec As New EntityCollection()
'ec.EntityTypeName = source.FirstOrDefault.EntityTypeName
For Each Entity In source
ec.Add(Entity)
Next
Return ec
End Function
Now, I don't imagine my problem would be solved if I change ByVal to ByRef in ToEntityCollection(), does it?
So how would I actually pass just a part of the collection byref to that function?
Thanks
EDIT after comments:
#Tim Schmelter it is for a nightly sync operation, having multiple selects on the database is more time intensive then storing the full dataset.
#Craig Are you saying that if i just leave it as an IEnumerable it will actually work? After all i call ToArray() in the createmultiple batch anyway so that wouldn't be too much of a problem to leave out...
#NetMage you're right i forgot to put in a key part of the code, here it is:
Public Class EntityCollection
Implements IList(Of Entity)
'...
Public Sub Add(item As Entity) Implements ICollection(Of Entity).Add
If IsNothing(EntityTypeName) Then
EntityTypeName = item.EntityTypeName
End If
If EntityTypeName IsNot Nothing AndAlso item.EntityTypeName IsNot Nothing AndAlso item.EntityTypeName <> EntityTypeName Then
Throw New Exception("EntityCollection can only be of one type!")
End If
Me.intList.Add(item)
End Sub
I Think that also explains the List thing... (BTW vb or c# don't matter i can do both :p)
BUT: You got me thinking properly:
Public Sub CreateMultiple(ByRef EntityCollection As EntityCollection)
'... do stuff to EC
Try
Dim ar = EntityCollection.ToArray()
Binding.CreateMultiple(ar) 'is also byref(webservice code)
EntityCollection.Collection = ar 'reset property, see below
Catch ex As SoapException
Raise(GetCurrentMethod(), ex)
End Try
End Sub
And the evil part( at least i think it is) :
Friend Property Collection As Object
Get
Return Me.intList
End Get
Set(value As Object)
Me.Clear()
For Each e As Object In value
Me.Add(New Entity(e))
Next
End Set
End Property
Now, i would still think this would work, since in my test if i don't use Linq or ToEntityCollection the byref stuff works perfectly fine. It is just when i do the batch thing, then it doesn't... I was guessing it could maybe have to do with me storing it in a local variable?
Thanks already for your time!
Anton
The problem was that i was replacing the references of Entity in my local batch, instead of in my big collection... I solved it by replacing the part of the collection that i sent as a batch with the batch itself, since ToList() and ToEntityCollection both create a new object with the same reference values...
Thanks for putting me in the correct direction guys!

Pass value from form to button text vb.net

I am learning vb.net and I'm having issues searching for what I need. I want to create a button that is "re-usable" throughout my application without needing to write code for each instance. So, what I would like to start with is take a variable in a form, example, public integer value and when this value changes I want to write to the text of a button. I know I can easily do this by writing code in the form btn_xxx.text = variable, but what if I have several buttons and each button looks at the same variable? Currently what I do is create a component which inherits a button and have a timer that on tick will look at the variable and write to the text. I'm sure there is a better way. Can anyone point me in the right direction? I know part of my problem is I don't know the nomenclature on what things are called, so hopefully I asked my question without too much confusion.
I saw this, https://www.daniweb.com/programming/software-development/threads/124842/detect-variable-change, but I don't see how to adapt that to my situation.
Here is what I have:
Private WithEvents Active_Alarm As New Nav_Active_Alarm
Then inside of a sub that calculates the count:
Active_Alarm.Count = CInt(dt_Active_Alarms.Rows.Count)
The user control:
Public Class Nav_Active_Alarm
Private mActive_Alarm_Count As Integer
Public Event Active_Alarm_Count_Changed(ByVal mvalue As Integer)
Public Property Count() As Integer
Get
Count = mActive_Alarm_Count
End Get
Set(ByVal value As Integer)
mActive_Alarm_Count = value
If Not Me.DesignMode Then
RaiseEvent Active_Alarm_Count_Changed(mActive_Alarm_Count)
test()
End If
End Set
End Property
Private Sub test()
If Not Me.DesignMode Then
If mActive_Alarm_Count = 0 Then
Me.btn_Goto_Active_Alarm.Image = My.Resources.Alarm_Clock_Static
'console or msgbox will work but updating the image will not
Else
Me.btn_Goto_Active_Alarm.Image = My.Resources.Alarm_Clock_Animation
'console or msgbox will work but updating the image will not
End If
End If
End Sub
End Class
If I write to console or add a msgbox I will see the event working. But, the image will not change. If I call the test sub from a timer it will work. Why won't the button update (by the way, I did try refresh and update in the code)?
Observer pattern is what you probably looking for.
This is quick and dirty.
Create a class to hold the variable value. Add a method that adds a button instance to a list.
Then a button that needs to know about the variable calls the register method.
When the value of the variable changes, it iterates through the list of buttons and sets the Text property of each one.
You might have jumped in a bit too deep too quick here. Google Custom data binding in .net, there's loads of built in stuff you can use. Though do it yourself is a good exercise.
A simple method to do this might be:
Create a form level list to hold the buttons you are interested in
Add the buttons you are interested in, into the list (maybe in form load or some other place where you have initialization code)
Create a private property in your form with a backing variable to hold the value you want to have applied to the buttons. In the setter portion spin through the list and set each buttons text.
Dim lstButtons As New List(Of Button)
Sub SetupButtons()
'call from form load or other init code
lstButtons.Add(btnPopulate)
lstButtons.Add(btnPopulate)
End Sub
Private _buttonText As String
Private Property ButtonText As String
Get
Return _buttonText
End Get
Set(value As String)
_buttonText = value
For Each b As Button In lstButtons
b.Text = value
Next
End Set
End Property
When you set the property - which now acts as your variable - it will update all of your textboxes for you.
I realize you mentioned without having to write code - but something has to tie things together. Even if you used the observer pattern (which is an elegant solution for this - so props to those who suggested it) you'd probably end up creating a class to hold the property and have that class implement the INotifyPropertyChanged from System.ComponentModel, and then you'd also have to have each button have a databinding for its text property to the property in the object of your class. There isn't really a way (that I can think of) to get around having to write some code for each form you do this in (though the class part you'd only have to write once of course).

Weird behavior using the Observer pattern

Ok, so I have an application that reads another processes memory. I initially had multiple scanning threads for the various areas I needed to read. This was processor intensive so I decided to go with the observer pattern. All was well except that I am having a weird behavior.
Here is what is happening
I have 2 radars (overlay and mapped) Both have a watcher class that attaches to the memory scanner and is notified on a new list of mobs.
so I open radar 1 (mapped) it attaches it's watcher to the scanner and waits for mob list update notifications
Open radar 2 (overlay). same thing happens and another watcher is attached.
all is well and good so far
Now there are properies on the mobs in the list, one of which is IsFilteredOut. This property is set in the radar code after it receives the list.
Now the weird behavior is that no matter what I do, the second radar to be opened changes all the properties of the mobs in the list of both radars. It is as if I am passing the list by ref, but I am not. I actually create a new instance of the moblist class every time I pass the list.
Here is the notify code. As you can see I create a new instance of the moblist class each pass.
Private Sub NotifyMobListUpdated(ByVal Mobs As List(Of MobData))
If Mobs IsNot Nothing Then
For Each w As Watcher In _watchers
If w.Type And WatcherTypes.MobList = WatcherTypes.MobList OrElse w.Type And WatcherTypes.All = WatcherTypes.All Then
w.MobListUpdated(New MobList(Mobs))
End If
Next
End If
End Sub
This is where it is handled in the Watcher class
''' <summary>
''' IWatcher MoblistUpdated Implementation
''' </summary>
''' <param name="Mobs">The Updated mob list</param>
''' <remarks></remarks>
Public Sub MobListUpdated(ByVal Mobs As MobList) Implements IWatcher.MobListUpdated
Try
PostNewMobList(Mobs)
Catch ex As Exception
End Try
End Sub
Public Sub PostNewMobList(ByVal Mobs As MobList)
_sync.Post(New SendOrPostCallback(AddressOf OnNewMobList), Mobs)
End Sub
Private Sub OnNewMobList(ByVal state As Object)
Dim mobs As MobList = TryCast(state, MobList)
Try
If mobs IsNot Nothing Then
RaiseEvent NewMobList(mobs)
End If
Catch ex As Exception
End Try
End Sub
This error is driving me nuts and any help would be greatly appreciated.
Thanks
I actually create a new instance of the moblist class every time I pass the list.
Which only prevents the list from changing, not the list elements. You'd have to clone the element objects as well. I don't have a clue with radars and mobs do, you might want to consider using Send instead of Post.