Important note: After its completion, this series will be gathered up, updated/polished and published as an eBook. Interested? Register to receive the eBook by sending us an email at telerik.testing@telerik.com.
Test Studio ships three major releases per year, each followed by a Service with new features and enhancements, as well as numerous minor releases in the form of internal builds with bug fixes and small feature improvements.
For major releases we define two important timeframes:
For service packs, we define one milestone:
Note: Key approach is to prepare automation for new features before the release, so automation coverage daily runs can be performed prior to release to verify last minute priority changes
We exclusively use Telerik Test Studio to automate Test Studio and provide internal feedback by doing so. In addition, for some specific scenarios, we use MS UI Automation calls in our .tstests to simulate specific Windows user interactions which are then handled by Test Studio, like showing context menu in a Browser during Test Studio Recording. For some other custom scenarios we call SOAP UI web service tests within Test Studio tests and analyze the output, to cover End-To-End (E2E) cases. Key approaches we use for the automation include:
Working with common tests, automation helper classes and global constants and variables are heavily utilized and recommended by the Test Studio testing team. Rule of thumb is if the same chunk of test steps/code is used more than twice across the project, it should be moved to a common test/code.
var row = (System.Data.DataRow)
this
.ExecutionContext.DataSource.Rows[0];
row[
"TestName"
] =
"test2"
;
UI automation in general is not as fast as API or low level automation, since the tester has to ensure the UI is properly visualized and refreshed before a certain test step is executed. In Test Studio there is a Step property called WaitForNoMotion for WPF/SL elements that takes care of this. Appropriate usage of this property can save execution time without compromising test stability.
Example: when opening a new Window, first step (verification or action) should always have WaitForNoMotion=true to ensure UI is loaded fully, which can take 1-2 seconds before its execution. However if after this initial step there are 20 other steps that check the UI for example or do actions on controls that don’t change in the current context, setting WaitForNoMotion=false for those steps will get rid of these 1-2 seconds per step delay that ensures UI is properly loaded, because the user already knows this is the case and some 10-20 seconds are saved and execution is accelerated. When applying this approach to a large number of steps in big projects, the accumulated savings in time can be measured up to an hour.
There are cases when we want to simulate Windows user actions while the Telerik Test Studio engine is running to see if it behaves properly—for example simulating user actions while the Test Studio recorder is running to see if steps are recorded properly. We do this by defining helper classes with common methods using MS UI Automation:
using
System.Windows.Automation;
public
static
void
ShowContextMenu(AutomationElement element,
int
inpos,
int
offset)
{
Assert.IsNotNull(element,
"The input element is null - stop execution"
);
var p = element.Current.BoundingRectangle;
System.Drawing.Point poi =
new
System.Drawing.Point(Convert.ToInt32(p.X)+inpos,Convert.ToInt32(p.Y+inpos));
Cursor.Position = poi;
System.Threading.Thread.Sleep(3000);
poi =
new
System.Drawing.Point(Convert.ToInt32(p.X) + offset, Convert.ToInt32(p.Y + offset));
Cursor.Position = poi;
System.Threading.Thread.Sleep(2000);
}
string projVersion;
if
(executionContext.Test.ProjectId.ToString() == projVersion)
public
void
OnBeforeTestStarted(ExecutionContext executionContext, ArtOfTest.WebAii.Design.ProjectModel.Test test)
{
if
(iskillenabled)
{
procsToKill =
new
string[] {
"iexplore"
,
"Chrome"
,
"Safari"
,
"firefox"
,
"ExpenseItStandalone"
,
"LogonScreen"
,
"WerFault"
,
"wcat"
,
"WpfApplication1"
,
"WpfApplication2"
,
"WpfApplication3"
,
"devenv"
,excel
","
slauncher
","
vsjitdebugger
","
plugin-container"};
foreach (string pr in procsToKill)
{
KillProcessByName(pr);
}
if
(executionContext.Test.Path.StartsWith(
"Scheduling"
))
{
RestartWindowsService(@
"Telerik Storage Service"
);
RestartWindowsService(@
"Telerik Scheduling Service"
);
}
}
}
System.Timers.Timer stopWatch;
public
void
OnBeforeTestStarted(ExecutionContext executionContext, ArtOfTest.WebAii.Design.ProjectModel.Test test)
{
stopWatch =
new
System.Timers.Timer(timeout);
stopWatch.Elapsed += StopWatchElapsed;
stopWatch.Start();
}
private
void
StopWatchElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
procsToKill =
new
string[] {
"iexplore"
,
"Chrome"
,
"Safari"
,
"firefox"
,
"ExpenseItStandalone"
,
"LogonScreen"
,
"WerFault"
,
"wcat"
,
"WpfApplication1"
,
"WpfApplication2"
,
"WpfApplication3"
,
"devenv"
,
"excel"
,
"slauncher"
,
"vsjitdebugger"
,
"plugin-container"
};
foreach (string pr in procsToKill)
{
KillProcessByName(pr);
}
}
public
void
OnAfterTestCompleted(ExecutionContext executionContext, TestResult result)
{
stopWatch.Stop();
}
public
void
OnBeforeTestListStarted(TestList list)
{
//create product version specific variable
outputDailiyFile =
"DailyRun"
+ list.CurrentVersion.ToString();
//read configuration file
if
(String.IsNullOrEmpty(projVersion)) ReadDLLConfiguration(outputDailiyFile);
//execute this section only for the Automation project
if
(projVersion == list.ProjectId.ToString())
{
isCurrentProject =
true
;
//prepare execution to re-run failed tests
if
(!rerun || list.TestListName.Contains(
"FailedReRun"
))
return
;
//create new TestList object
failedTL =
new
TestList(list.TestListName.ToString() +
"(FailedReRun)"
,
"Automatic"
, ArtOfTest.WebAii.Design.TestListType.Automated);
failedTL.ProjectId = list.ProjectId;
failedTL.Id = list.Id;
failedTL.Settings = list.Settings;
}
}
And execute it runtime also:
public
void
OnAfterTestListCompleted(RunResult result)
{
//Only execute if re-run failed tests is selected
if
(!rerun || !isFailed)
return
;
//get the list of failed tests for re-run
var failedtestnames = result.TestResults.Where(x => x.Result == ArtOfTest.Common.Design.ResultType.Fail).ToList();
if
(rerunAsList)
{
foreach (TestResult tr in failedtestnames)
{
failedTL.Tests.Add(
new
TestInfo(tr.TestId.ToString(), tr.TestPath.ToString()));
}
failedTL.SaveToListFile(projRoot);
StartAOTProcess(failedTL.TestListName.ToString() +
".aiilist"
, projRoot);
}
else
{
foreach (TestResult tr in failedtestnames)
{
StartAOTProcess(tr.TestPath.ToString(), @projRoot);
}
}
}
Did you find these tips helpful? Stay tuned for the next chapter and let us know your feedback. And don't forget to register to receive the eBook that will be put together when this series is complete.
If you are interested in trying the latest Test Studio, feel free to go and grab your free trial.
Daniel was the QA Architect of the Telerik ALM and Testing division.