I'm using VS2010 Premium, Coded UI Tests.
Do you know how to re-execute failed test cases after run?
If test was passed after re-execution then it should be passed in result report.
Not so optimal way but you could put all your code to try/catch block and rerun the test if an exception is thrown:
[CodedUITest]
public class CodedUITest
{
private static int _maxTestRuns = 5;
[TestCleanup]
public void Cleanup()
{
//If the test has reached the max number of executions then it is failed.
if (_maxTestRuns == 0)
Assert.Fail("Test executed {0} times and it was failed", _maxTestRuns);
}
[TestMethod]
public void CodedUITestMethod()
{
try
{
this.UIMap.RecordedMethod1();
}
catch (Exception exception)
{
//Call Cleanup, rerun the test and report the error.
if (_maxTestRuns > 0)
{
_maxTestRuns--;
TestContext.WriteLine(exception.Message);
TestContext.WriteLine("Running Again...");
this.Cleaup();
this.CodedUITestMethod();
}
}
}
}
You could also generalize the method Schaliasos proposes, we could create a base class like this:
[CodedUITest]
public class _TestBase
{
private static int _maxTestRuns;
public Exception _currentException;
public _TestBase()
{
}
public void TryThreeTimes(Action testActions)
{
_maxTestRuns = 3;
_currentException = null;
while (_maxTestRuns > 0)
{
try
{
testActions();
}
catch (Exception exception)
{
_maxTestRuns--;
_currentException = exception;
}
if (_currentException == null)
break; // Test passed, stop retrying
}
if (_maxTestRuns == 0) // If test failed three times, bubble up the exception.
{
throw _currentException;
}
}
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext context
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
private TestContext testContextInstance;
}
And then when we write tests we could inherit the class above and do this:
[CodedUITest]
public class NewTestClass : _TestBase
{
[TestMethod]
public void MyTestMethod1()
{
TryThreeTimes(new Action(() =>
// Assertions and Records come here
Assert.IsTrue(false);
}));
}
[TestMethod]
public void MyTestMethod2()
{
TryThreeTimes(new Action(() =>
// Assertions and Records come here.
Assert.IsTrue(true);
}));
}
}
I have been thinking about how this could be made even simpler, any suggestions would be appreciated. This at least saves quite a bit of code if you have many tests that you would like to run often, maybe it would make sense for some to generalize the function TryThreeTimes so one of the arguments would be the number of reruns.
Related
A field of MongoDB Entity MyCardDO, explicitly set it to unique
#Indexed(unique=true)
private String uid;
and there is a MyCardService to crud MyCardDO, and there is a MyCardServiceTest to test MyCardService, there is a add_repeat_uid_record_failed inner MyCardServiceTest to test the uid cannot be duplicated,
MyCardDO myCardDO1 = new MyCardDO();
myCardDO1.setUid("1");
myCardService.add(myCardDO1);
try {
MyCardDO myCardDO2 = new MyCardDO();
myCardDO2.setUid("1");
myCardService.add(myCardDO2);
Assert.fail();
} catch (DuplicateKeyException e) {
assertTrue(e.getMessage().contains("E11000 duplicate key error collection: opportunity-test.pro_mycard index: uid dup key: { : \"1\" }"));
}
If I run this test method directly it's OK, but I run the whole MyCardServiceTest this method is failed, and from Wireshark I know the createIndexes only executed once, if dropped the collection it will not createIndexes again
#After
public void tearDown() {
mongoTemplate.dropCollection(MyCardDO.class);
}
So how to let spring to execute createIndexes before every test method? that is
#Before
public void setUp() {
// how to auto execute createIndexes before every test method
// prepare some test data
myCardService.add(myCardDO1);
}
p.s.
#RunWith(SpringRunner.class)
#DataMongoTest(includeFilters = #ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,value={MyCardService.class}))
#ActiveProfiles("test")
#Import(SpringMongoConfig.class)
public class MyCardServiceTest {
//...
}
Wireshark screenshot
Final my resolution :
#After
public void tearDown() {
mongoTemplate.remove(new Query(), MyCardDO.class);
}
#AfterClass
public static void finalClean() {
mongoTemplate.dropCollection(MyCardDO.class);
}
that is after finished every test method only delete all records and at final when the whole test class is finished to drop the collection.
I have the following tryout code:
[TestMethod]
public void VisibilitySucces()
{
testPage.HideParagraph();
testPage.ShowParagraph();
}
[TestMethod, ExpectedException(typeof(WebDriverTimeoutException))]
public void ShouldBeVisibleException()
{
testPage.ShouldBeVisibleException();
}
[TestCleanup]
public void TestCleanup()
{
switch (TestContext.CurrentTestOutcome)
{
case UnitTestOutcome.Passed:
Console.WriteLine("Passed!");
break;
default:
Console.WriteLine("The test outcome is " + TestContext.CurrentTestOutcome.ToString());
break;
}
Browser.Quit();
}
Now, the first test has the outcome Passed as expected.
The second test does throw the exception (I've tested it without the ExpectedException attribute). It's marked as passed visually, but the outcome in the console is showing InProgress.
How can this be when this status is queried in the TestCleanup?
Below is an Example.
public class MyController : Controller
{
[Route("~/api/mycontroller")]
[HttpGet]
public int ID()
{
try
{
return somecontroller.getID(ID);
}
catch (Exception ex)
{
throw ex;
}
}
}
Above it the controller that is fetching the ID from the below controller.
Below is the controller that it is inherited.
public class Controller : ApiController
{
public int ID
{
get
{
return int.Parse(HttpContext.Current.Request.Headers["ID"]);
}
}
}
How do i write unit test case for the following.???
Oh, unit testing HttpContext.Current. That's one of my favorites :-)
You can't write a unit test for something that depends on HttpContext.Current. So if you want to write testable code the first step is to search in your entire solution for the HttpContext.Current keyword and simply wipe them out from existence.
In this particular case you would of course replace them with the corresponding abstraction:
public class Controller : ApiController
{
public int ID
{
get
{
return int.Parse(Request.Headers.GetValues("ID").FirstOrDefault());
}
}
}
Now it's completely trivial to unit test your Web API controller properly:
// arrange
var sut = new MyController();
sut.Request = new HttpRequestMessage();
sut.Request.Headers.TryAddWithoutValidation("ID", "5");
// act
var actual = sut.SomeControllerAction();
// assert
Assert.AreEqual(5, actual);
I am trying out Moles on a home project to (hopefully) be able to recommend that it be adopted in projects at work. I am working with VS 10.0.30319 and Moles 1.0.0.0.
I have created the following class:
public class DeveloperTestControlBL
{
public static bool VerifyCurrentDevelopmentStatus(int tpid, int testStatusID)
{
return false; // For this example, always return false,
// so that a return of true means the delegation worked
}
}
In my test class, I have created a test which tests a class which calls the VerifyCurrentDevelopmentStatus method. I would have expected to have a declaration of the form:
[TestMethod]
[HostType("Moles")]
public void TestPreTCIToEditReady_WithMoles()
{
var devTCBL = new SDeveloperTestControlBL();
devTCBL.VerifyCurrentDevelopmentStatus = delegate(int tpid, int testStatusID)
{
return true;
}
// rest of the test here
}
What I have found is that to set the delegate I have to do this:
[TestClass]
public class MyTest
{
[TestMethod]
[HostType("Moles")]
public void TestPreTCIToEditReady_WithMoles()
{
DelegateExample.Moles.MDeveloperTestControlBL.VerifyCurrentDevelopmentStatusInt32Int32 =
VerifyCurrentDevelopmentStatusAlwaysTrue;
// Rest of the test here
}
private bool VerifyCurrentDevelopmentStatusAlwaysTrue(int tpid, int status)
{
return true;
}
Does anyone have any advice as to what I am doing incorrectly? I have the
using Microsoft.Moles.Framework; statement and have a reference to DeveloperTestControlBL.Moles in the test project.
Thanks in advance,
Ron L
Try this
devTCBL.VerifyCurrentDevelopmentStatus (delegate(int tpid, int testStatusID)
{
return true;
});
It worked for me.
I have a 2010 Coded UI Test that performs some actions against a website. I am able to add a datasource to a "Test Method" which loops the entire method once per record.
But, what I really want to do is loop only a portion of the test which is just a single recorded method in the UIMap.
Let's say the test method looks something like this:
//[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "|DataDirectory|\\TestCommunities.xml", "Community", DataAccessMethod.Sequential), DeploymentItem("Tests\\WebTests\\DataSources\\TestCommunities.xml"), TestMethod]
public void LoginCreateCommunities()
{
this.UIMap.LoginAdmin();
//this.UIMap.CreateCommunityParams.UIItem0EditText = TestContext.DataRow["CommunityName"].ToString();
this.UIMap.CreateCommunity();
this.UIMap.LogoffClose();
}
It's only UIMap.CreateCommunity() that I want to loop the datasource. I do not want all 3 methods to execute per record in the datasource, which is what happens when I attach the datasource to the test method (the portion commented out above).
Is there a way to achieve what I'm trying to do here?
Thanks.
You have to use the ClassInitialize and ClassCleanup methods. You place it in the #region Additional test attributes area at the bottom. So for you it'd look something like:
#region Additional test attributes
[ClassInitialize]
static public void ClassInit(TestContext context)
{
Playback.Initialize();
try
{
sharedTest.LoginAdmin();
}
finally
{
Playback.Cleanup();
}
}
[ClassCleanup]
static public void ClassCleanup()
{
Playback.Initialize();
try
{
sharedTest.LogoffClose();
}
finally
{
Playback.Cleanup();
}
}
#endregion
first you have to define a new UIMap in your codedUI class
[CodedUITest]
public class CodedUITest1
{
static private UIMap sharedTest = new UIMap();
....
[ClassInitialize()]
static public void ClassInit(TestContext context)
{
Playback.Initialize();
try
{
sharedTest.RecordedStartApp();
}
finally
{
Playback.Cleanup();
}
}
[ClassCleanup()]
static public void ClassCleanup()
{
Playback.Initialize();
try
{
sharedTest.RecordedCloseApp();
}
finally
{
Playback.Cleanup();
}
}
}