Call Testing: How to Set Up Common for All Test Sets

Is there a way to find out in the JUnit 4 test class if the class was initiated by Test-Suite? I have global things that I want to run before all tests (regarding the database in memory), so I thought that I was doing this in a test suit. However, I still want to be able to initiate one test at a time without a test suit. So I need to know if I need to initialize global things in the @Before part of the test ... Does anyone know if this is possible?

+6
source share
3 answers

There are several ways to achieve this. The simplest and easiest way is to have a β€œtest” that runs at the beginning and end of your package, which set up your database and then sets a global flag. In your @Before and @After tests, you check this flag and, if necessary, configure / disable.

@RunWith(Suite.class) @SuiteClasses({SetupTest.class, RealTest.class, TeardownTest.class}); 

This is the simplest solution, but it is not very nice, so using TestRule will be a more convenient solution. Take a look at the ExternalResource extension. This implements before and after the logic that surrounds your testing methods. This will allow you to separate the @Before and @After methods to reuse the same code everywhere.

Then for your package you need to implement before and after the logic. Unfortunately, the class annotated with @RunWith (Suite.class) has not actually been created, so you cannot use the constructor of this class, but you can extend Suite . Depending on how you run this, you will need to implement one of the constructors using @RunWith as an example:

 public class MySuite extends Suite { /** * 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 // set global variable } } 

Then run the test suite with

 @RunWith(MySuite.class) 

There are several constructors that are used in different situations, look at the comments next to each of them. You still need to use a global variable so that your Rules do not restart the installation code. The above will work if you want to execute only the setup code, executing the break code is more complicated, but can be done. Let me know if you need it :-)

If you need more flexibility (for example, executing installation code for specific methods only), see my answer to How to define a JUnit method rule in a package? .

+5
source

I would use JUnit @BeforeClass and @AfterClass annotations to indicate methods for doing this type of work.

From @BeforeClass Javadoc:

Sometimes, several tests must share an expensive computing setup (such as entering a database). Although this can jeopardize the independence of the tests, sometimes it is a necessary optimization. Annotating the public static void no-arg method with @BeforeClass reasons it runs once before any of the testing methods in the class. @BeforeClass superclass methods will execute before those of the current class.

+2
source

In each test suite, you can put the @BeforeClass code, which delegates a helper class that performs the general setup. The helper class may have a static boolean , which records whether the customization has already been configured. If this has already been done, the helper class will do nothing.

0
source

Source: https://habr.com/ru/post/902600/


All Articles