Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TestNG - @BeforeMethod for specific methods

I'm using Spring Test with TestNG to test our DAOs, and I wanted to run a specific text fixture script before certain methods, allowing the modifications to be rolled back after every method so that the tests are free to do anything with the fixture data.

Initially I thought that 'groups' would be fit for it, but I already realized they're not intended for that (see this question: TestNG BeforeMethod with groups ).

Is there any way to configure a @BeforeMethod method to run only before specific @Tests? The only ways I see are workarounds:

  • Define an ordinary setup method and call at the beginning of every @Test method;
  • Move the @BeforeMethod method to a new class (top level or inner class), along with all methods that depend on it.

Neither is ideal, I'd like to keep my tests naturally grouped and clean, not split due to lack of alternatives.

like image 323
user2479523 Avatar asked Dec 17 '13 17:12

user2479523


People also ask

What is the difference between @BeforeTest and @BeforeMethod in TestNG?

@BeforeTest method executes only once before the first @Test method. @BeforeClass executes before each class. If there are separate @BeforeTest and @BeforeClass methods in different classes, then all the @BeforeTest methods will execute first but @BeforeClass methods will be executing as per the respective classes.

What is the use of @BeforeMethod annotation?

The @BeforeMethod is specific to a class not to an XML file. The @BeforeMethod annotated method will be invoked before the execution of each test method where the test method is nothing but a test case.

Can we have multiple BeforeMethod?

Well, nope, its configured to run just once per group. If that is what you want, then you can continue using your example but in your xml file, make different <test> for each group.

What is BeforeMethod in TestNG?

Types of TestNG Annotations Let's explore how these methods work. @BeforeMethod: This will be executed before every @test annotated method. @AfterMethod: This will be executed after every @test annotated method. @BeforeClass: This will be executed before first @Test method execution.


2 Answers

You could add a parameter your @BeforeMethod with the type 'java.lang.reflect.Method'. TestNG will then inject the reflection information for the current test method including the method name, which you could use for switching.

If you add another 'Object' parameter, you will also get the invocation parameters of the test method.

You'all find all on possible parameters for TestNG-annotated methods in chapter 5.18.1 of the TestNG documentation.

like image 95
jabbrwcky Avatar answered Sep 19 '22 12:09

jabbrwcky


Tests are simply not designed to do this. Technically speaking, a single tests is supposed to handle being idempotent for itself meaning it sets up, tests, and takes down. That is a single test. However, a lot of tests sometimes have the same set-up and take down method, whereas other tests need one set-up before they all run. This is the purpose of the @Before type tags. If you don't like set-up and tear-down inside your test, your more then welcome to architect your own system, but technically speaking, if certain methods require specific set-ups or tear-downs, then that really should be embodied IN the test, since it is a requirement for test to pass. It is ok to call a set-up method, but ultimately, it should be OBVIOUS that a test needs a specific set-up in order to pass. After all, if your using specific set-ups, aren’t you actually testing states rather than code?

like image 28
Nick Humrich Avatar answered Sep 21 '22 12:09

Nick Humrich