Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a equivalent of testNG's @BeforeSuite in JUnit 4?

I'm new to the test automation scene so forgive me if this is a stupid question but google has failed me this time. Or at least anything I've read has just confused me further.

I'm using JUnit 4 and Selenium Webdriver within Eclipse. I have several tests that I need to run as a suite and also individually. At the moment these tests run fine when run on their own. At the start of the test an input box is presented to the tester/user asking first what server they wish to test on (this is a string variable which becomes part of a URL) and what browser they wish to test against. At the moment when running the tests in a suite the user is asked this at the beginning of each test, because obviously this is coded into each of their @Before methods.

How do I take in these values once, and pass them to each of the test methods?

So if server = "server1" and browser = "firefox" then firefox is the browser I want selenium to use and the URL I want it to open is http://server1.blah.com/ for all of the following test methods. The reason I've been using seperate @Before methods is because the required URL is slightly different for each test method. i.e each method tests a different page, such as server1.blah.com/something and server1.blah.com/somethingElse

The tests run fine, I just don't want to keep inputting the values because the number of test methods will eventually be quiet large.

I could also convert my tests to testNG if there is an easier way of doing this in testNG. I thought the @BeforeSuite annotation might work but now I'm not sure.

Any suggestions and criticism (the constructive kind) are much appreciated

like image 412
user1088166 Avatar asked Dec 08 '11 17:12

user1088166


People also ask

What is the use of @BeforeSuite annotation?

@BeforeSuite annotated method will be run before the execution of all the test cases defined in the folder or inside a TestNG suite. For example, this annotation is used when you have separate URLs to test all your test cases. Environment variables can be set in a @BeforeSuite annotated method.

How TestNG is better than JUnit?

JUnit is an open-source framework used to trigger and write tests. TestNG is a Java-based framework that is an upgraded option for running tests. JUnit does not support to run parallel tests. TestNG can run parallel tests.

How do you use cucumber BeforeSuite?

As the part of Extended Cucumber Runner there are 2 additional annotations introduced. They are: @BeforeSuite - annotates method which is supposed to run before the entire test suite starts. @AfterSuite - annotates method which is supposed to run after the entire test suite ends.

Why do you use TestNG And why not JUnit?

JUnit does not include any dependency tests. TestNG includes dependency tests. JUnit is a framework that is open-source and may be used to write and trigger tests. TestNG is a Java-based framework that provides an improved way to run tests.


2 Answers

You can adapt the solution for setting a global variable for a suite in this answer to JUnit 4 Test invocation.

Basically, you extend Suite to create MySuite. This creates a static variable/method which is accessible from your tests. Then, in your tests, you check the value of this variable. If it's set, you use the value. If not, then you get it. This allows you to run a single test and a suite of tests, but you'll only ask the user once.

So, your suite will look like:

public class MySuite extends Suite {
    public static String url;

    /**
     * Called reflectively on classes annotated with <code>@RunWith(Suite.class)</code>
     * 
     * @param klass the root class
     * @param builder builds runners for classes in the suite
     * @throws InitializationError
     */
    public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
        this(builder, klass, getAnnotatedClasses(klass));
        // put your global setup here
        MySuite.url = getUrlFromUser();
    }
}

This would be used in your Suite like so:

@RunWith(MySuite.class)
@SuiteClasses({FooTest.class, BarTest.class, BazTest.class});

Then, in your test classes, you can either do something in the @Before/@After, or better look at TestRule, or if you want Before and After behaviour, look at ExternalResource. ExternalResource looks like this:

public static class FooTest {
    private String url;

    @Rule
    public ExternalResource resource= new ExternalResource() {
        @Override
        protected void before() throws Throwable {
            url = (MySuite.url != null) ? MySuite.url : getUrlFromUser();
        };

        @Override
        protected void after() {
            // if necessary
        };
    };

    @Test
    public void testFoo() {
        // something which uses resource.url
    }
}

You can of course externalize the ExternalResource class, and use it from multiple Test Cases.

like image 139
Matthew Farwell Avatar answered Nov 15 '22 06:11

Matthew Farwell


I think the main functionality of TestNG that will be useful here is not just @BeforeSuite but @DataProviders, which make it trivial to run the same test with a different set of values (and won't require you to use statics, which always become a liability down the road).

You might also be interested in TestNG's scripting support, which makes it trivial to ask the user for some input before the tests start, here is an example of what you can do with BeanShell.

like image 30
Cedric Beust Avatar answered Nov 15 '22 04:11

Cedric Beust