Consider following example code:
public class testcases()
{
#Before method
public void setup()
{
-----------
some code
-----------
}
#Test
public void test1()
{
---------- some code-----
}
#Test
public void test2()
{
---------- some code-----
}
#After method
public void setup()
{
-----------
some code
-----------
}
}
Now i will a create hub and launch 2 firefox nodes. i want the method test1() to run in one firefox node and the method test2() in another firefox node. Please let me know how to configure this using testng.xml file
Basically you want to run your testcases in parallel. In the testng xml in your suite declaration you would need to add parallel="methods". Options for the parallel values include, classes, tests, instances,false.
<suite thread-count="10" verbose="1" parallel="methods" ......>
Make sure your thread-count value is set appropriately, i.e. how many threads should be spawned. The Grid would take care of distribution of the parallel tests. Thing that you need to watch out for is make sure your driver object is different for each thread for the commands to go to proper driver object.
Related
I know that unit tests should run isolated and should never depend on other unit tests.
However, I also write some integration tests with MSTest and sometimes they produce a result that I would like to reuse in another test.
For example:
Creating a user
Searching this user from the database
Deleting the user
Each of those points would be an integration test for me, so I would like to write methods that look like this:
User _myNewUser;
[TestMethod]
public void CreateAUserTest()
{
//User gets created here somehow....
_myNewUser = successfullyCreatedUser;
}
And this test should run after the preceeding test:
User _myNewUser;
[TestMethod]
public void SearchingUserTest()
{
var user = searchUser(_newUser.GetName());
//Assert that user is not null
}
You can see that I use the value of the first test in the second test.
With a playlist I could make sure that both tests run in the correct order.
However, in VS 2022 each test gets executed in isolation, so what I am trying to do does not work.
_newUser is always null if I run the second test, even if the first test was a success.
Is my idea bad in general?
If not: How can I use the produced data of a test in another test?
I usually extract the contents of a test like that into a separate staging function that does not contain the [TestMethod] attribute, so that I can reuse it to stage other tests.
private void Stage_CreateAUser()
{
//do work from CreateAUserTest()
}
[TestMethod]
public void CreateAUserTest()
{
Stage_CreateAUser();
}
private void Stage_SearchingUser()
{
//do work from CreateAUserTest()
}
[TestMethod]
public void SearchingUserTest()
{
Stage_CreateAUser();
Stage_SearchingUser();
}
Etc...
As an example, I have:
#Test
public void login(*Code ommitted*){
That tests logging into a site.
Then I want to do other tests that start with logging in, so I've got:
#Test
public void sendUserInvite(){
login();
*Other code omitted*
}
Something is intuitively telling me this is really bad practise, but at the same time if the login test does what I need it to, so why not re-use it in this way? Can anyone clarify this. After a while I end up doing several tests at the start of another test because they are the pre-conditions in order to carry out a particular test.
If you're using TestNG, you can use #BeforeClass, #BeforeSuite, #BeforeTest, #BeforeMethod etc. in order to launch your preconditions on some step before your #Test method
E.g. you have 2 tests in xml:
<suite name="Suite0" verbose="1" >
<test name="name0" >
<classes>
<class name="Test0" />
</classes>
</test>
<test name="name1">
<classes>
<class name="Test1"/>
</classes>
</test>
</suite>
Let's assume Test0 and Test1 both extend class BaseTest
Then in BaseTest:
public class BaseTest {
#BeforeTest
public void login() {
// smth w/ login
}
}
So, when the suite is launched, login method will be invoked. Just note that #BeforeTest will work for every test from a suite, not for every method with #Test, this sometimes confuses.
UPD
If you're using JUnit, you can use #Before, and method with it will be run before every #Test in a class. So to say, it is the same as #BeforeMethod in TestNG
#Before
public void pre() {
// your login here
}
#Test
public void testA() {
// prints A
}
#Test
public void testB() {
// prints B
}
#After
public void end() {
// logout
}
Order of execution:
login
A
logout
login
B
logout
According to the following links, JUnit test cases are designed to be run in isolation and each test should be independent of one other. I believe you have to reconsider your design and go for test framework like TestNG which perfectly suites your requirements.
Choose order to execute JUnit tests
running a subset of JUnit #Test methods
How to run test methods in specific order in JUnit4?
If you feel the need to call one test method from another test method, that's a good sign that you need to extract a class.
I suggest moving login to a PageObject class:
public class HomePage {
private final WebDriver driver;
public HomePage(WebDriver driver) {
this.driver = driver;
}
public WelcomePage login(String userName, String password) {
signIn(userName, password);
Assert.assertEquals("sign in failed", userName, getSignedInUser());
return new WelcomePage(driver, userName);
}
private void signIn(String userName, String password) {
// Add code to perform the sign in
}
public String getSignedInUser() {
// Add code to check the current page to see who is reported
// as the signed in user
}
}
Then your test looks like this:
#Test
public void login() {
HomePage page = new HomePage(driver);
page.login(TEST_USER_NAME, TEST_PASSWORD);
}
#Test
public void sendUserInvite() {
WelcomePage page = new HomePage(driver)
.login(TEST_USER_NAME, TEST_PASSWORD);
page.sendUserInvite(NON_USER_EMAIL_ADDRESS);
}
Of course, your page objects may also have some code duplication (for instance, getting the signed in user may be a common concern). When this happens, you can either extract a base class for all of our page objects or a helper class for common logic.
This is my scenario, i use webdriver with testNG for doing data driven test. I am observing that the data i am 'seeing' in web app which is provided by #dataprovider is missing some value. For exg if i have an array as {"1","2","3","4","5"}, i am getting these value in webdriver script using testNG #dataprovider, i am observing in the 'Web GUI' initially 2 might be displayed, then in the next iteration 5 is displayed then the test stop.
I am assuming that TestNG is not waiting for webdriver to complete the function or process.
Here is my sample code
#Test (dataProviderClass=MyDataProviders.class)
public class MyWebDriverClass{
#Test(dataProvider = "theProviderName")
public void providerHomeCreateuser(String arg1,String arg2)
{
<..input arg1, arg2 to text fields..>
}
}
I understand somewhere i need to put a Thread.wait(), could any body guide me on this.
Data provider method is as follows
public class MyDataProviders {
...
...
#DataProvider (name="theProviderName")
public static Object[][] getData() throws Exception
{
Object retObject[][]=getTableArray("src\\com\\abcd\\resource\\TestData.xls", 5, "MyTestData");
return retObject;
}
This is how my testNG test looks like:-
public class orderTest{
#Test
public void meth1() throws InterruptedException{
System.out.println("1");
Reporter.log("1");
}
#Test
public void meth2() throws InterruptedException{
System.out.println("2");
Reporter.log("2");
}
#Test
public void meth3() throws InterruptedException{
System.out.println("3");
Reporter.log("3");
}
#Test
public void meth4() throws InterruptedException{
System.out.println("4");
Reporter.log("4");
}
}
When i run it on eclipse, the console shows as :-
1
2
3
4
PASSED: meth1
PASSED: meth2
PASSED: meth3
PASSED: meth4
But when i open the testNG report, click on reporter output link, it shows as :-
Reporter output -
meth1
1
meth4
4
meth3
3
meth2
2
Why the order is not correct in the testng report?
order of execution is 1,2,3,4
but,
order of reporting is 1,4,3,2.
It can also be displayed by execution order in the output report. To do so, your TestNG Reporter should implement IReporter.
A good plugin that uses it is ReportNG.
You can override it's generateReport method, to display the suites in the Html report, by their parent XML suite order, like so:
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectoryName) {
...
Comparator<ISuite> suiteComparator = new TestSuiteComparator(xmlSuites);
suites.sort(suiteComparator);
...
}
Where the TestSuiteComparator is as follow:
public class TestSuiteComparator implements Comparator<ISuite> {
public List<String> xmlNames;
public TestSuiteComparator(List<XmlSuite> parentXmlSuites) {
for (XmlSuite parentXmlSuite : parentXmlSuites) {
List<XmlSuite> childXmlSuites = parentXmlSuite.getChildSuites();
xmlNames = new ArrayList<String>();
xmlNames.add(parentXmlSuite.getFileName());
for (XmlSuite xmlsuite : childXmlSuites) {
xmlNames.add(xmlsuite.getFileName());
}
}
}
#Override
public int compare(ISuite suite1, ISuite suite2) {
String suite1Name = suite1.getXmlSuite().getFileName();
String suite2Name = suite2.getXmlSuite().getFileName();
return xmlNames.indexOf(suite1Name) - xmlNames.indexOf(suite2Name);
}
}
If you want the classes and methods listed in this file to be run in an unpredictible order, set the preserve-order attribute to false.
That is what the TestNG documentation says, so unless the wrong spelling (not saying that mine is perfect :), that's a feature.
But it seems to me, that only the reporting order is unpredictable, the execution seems quite predictable.
The dtd says,
#attr preserve-order If true, the classes in this tag will be run in the same order as
found in the XML file.
so that matches what it actually does.
It's not wrong but maybe expected the other way round.
Seems to be a feature to make the reports more attractive :)
I begin studying Unit testing with "(NUnit)". I know that this type of testing is used to test "classes" , "functions" and the "interaction between those functions".
In my case I develop "asp.net web applications".
How can i use this testing to test my
pages(as it is considered as a class
and the methods used in)and in which sequence?, i have three layers:
Interface layer(the .cs of each page).
Data access layer(class for each entity)(DAL).
Database layer (which contains connection to the database,open connection,close connection,....etc).
Business layer(sometimes to make calculation or some separate logic).
How to test the methods that make connection to the database?
How to make sure that my testing not a waste of time?.
There are unit and integration tests. Unit testing is testing single components/classes/methods/functions and interaction between them but with only one real object (system under test-SUT) and test doubles. Test doubles can be divided to stubs and mocks. Stubs provide prepared test data to SUT. That way you isolate SUT from the environment. So You don't have to hit database, web or wcf services and so on and you have same input data every time. Mocks are used to verify that SUT works as expected. SUT calls methods on mock object not even knowing it is not real object. Then You verify that SUT works by asserting on mock object. You can write stubs and mocks by hand or use one of many mocking frameworks. One of which is http://code.google.com/p/moq/
If You want to test interaction w/database that's integration testing and generally is a lot harder. For integration testing You have to setup external resources in well known state.
Let's take your layers:
You won't be able to unit test it. Page is to tightly coupled to ASP.NET runtime. You should try to not have much code in code behind. Just call some objects from your code behind and test those objects. You can look at MVC design patters. If You must test Your page You should look at http://watin.org/. It automates Your internet browser, clicks buttons on page and verifies that page displays expected result's.
This is integration testing. You put data in database, then read it back and compare results. After test or before test You have to bring test database to well known state so that tests are repeatable. My advice is to setup database before test runs rather then after test runs. That way You will be able to check what's in database after test fails.
I don't really know how that differs from that in point no. 2.
And this is unit testing. Create object in test, call it's methods and verify results.
How to test methods that make connections to the database is addresed in point 2.
How to not waste time? That will come with experience. I don't have general advice other then don't test properties that don't have any logic in it.
For great info about unit testing look here:
http://artofunittesting.com/
http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530
http://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627/ref=sr_1_2?ie=UTF8&s=books&qid=1306787051&sr=1-2
http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054/ref=sr_1_1?ie=UTF8&s=books&qid=1306787051&sr=1-1
Edit:
SUT, CUT - System or Class under test. That's what You test.
Test doubles - comes from stunt doubles. They do dangerous scenes in movies so that real actors don't have to. Same here. Test doubles replace real objects in tests so that You can isolate SUT/CUT in tests from environment.
Let's look at this class
public class NotTestableParty
{
public bool ShouldStartPreparing()
{
if (DateTime.Now.Date == new DateTime(2011, 12, 31))
{
Console.WriteLine("Prepare for party!");
return true;
}
Console.WriteLine("Party is not today");
return false;
}
}
How will You test that this class does what it should on New Years Eve? You have to do it on New Years Eve :)
Now look at modified Party class
Example of stub:
public class Party
{
private IClock clock;
public Party(IClock clock)
{
this.clock = clock;
}
public bool ShouldStartPreparing()
{
if (clock.IsNewYearsEve())
{
Console.WriteLine("Prepare for party!");
return true;
}
Console.WriteLine("Party is not today");
return false;
}
}
public interface IClock
{
bool IsNewYearsEve();
}
public class AlwaysNewYearsEveClock : IClock
{
public bool IsNewYearsEve()
{
return true;
}
}
Now in test You can pass the fake clock to Party class
var party = new Party(new AlwaysNewYearsEveClock());
Assert.That(party.ShouldStartPreparing(), Is.True);
And now You know if Your Party class works on New Years Eve. AlwaysNewYearsEveClock is a stub.
Now look at this class:
public class UntestableCalculator
{
private Logger log = new Logger();
public decimal Divide(decimal x, decimal y)
{
if (y == 0m)
{
log.Log("Don't divide by 0");
}
return x / y;
}
}
public class Logger
{
public void Log(string message)
{
// .. do some logging
}
}
How will You test that Your class logs message. Depending on where You log it You have to check the file or database or some other place. That wouldn't be unit test but integration test. In order to unit test You do this.
public class TestableCalculator
{
private ILogger log;
public TestableCalculator(ILogger logger)
{
log = logger;
}
public decimal Divide(decimal x, decimal y)
{
if (y == 0m)
{
log.Log("Don't divide by 0");
}
return x / y;
}
}
public interface ILogger
{
void Log(string message);
}
public class FakeLogger : ILogger
{
public string LastLoggedMessage;
public void Log(string message)
{
LastLoggedMessage = message;
}
}
And in test You can
var logger = new FakeLogger();
var calculator = new TestableCalculator(logger);
try
{
calculator.Divide(10, 0);
}
catch (DivideByZeroException ex)
{
Assert.That(logger.LastLoggedMessage, Is.EqualTo("Don't divide by 0"));
}
Here You assert on fake logger. Fake logger is mock object.