I want to include multiple categories for a junit runner.
Java Code
#RunWith(Categories.class)
#IncludeCategory(IMAP.class , POP.class)
#SuiteClasses({MailTestSuites.class})
public class TestSuiteRunner{
}
I want to run my test suite for these two categories only. I have categories for mail suite like "IMAP,POP , SMTP , POP3". Now , I want to run only "IMAP , POP" category suites only.
How can I run with junit?
Up to version JUnit 4.11, #IncludeCategory and #ExcludeCategory only support one value. However, starting with the upcoming release 4.12, it will be allowed to pass multiple values.
According to the documentation in the source code, you can then write:
#RunWith(Categories.class)
#IncludeCategory({IMAP.class, POP.class})
#SuiteClasses({MailTestSuites.class})
No, you couldn't define multiple values of #IncludeCategory in one Categories.
I recommend you use multiple Categories to run your test cases. (Separate IMAP and POP test cases)
//IMAP tests
#RunWith(Categories.class)
#IncludeCategory(IMAP.class)
#SuiteClasses({MailTestSuites1.class})
public class TestSuiteRunner1{}
//POP tests
#RunWith(Categories.class)
#IncludeCategory(POP.class)
#SuiteClasses({MailTestSuites2.class})
public class TestSuiteRunner2{}
//Merge into one Test
#RunWith(Suite.class)
#Suite.SuiteClasses({TestSuiteRunner1.class,
TestSuiteRunner2.class})
public class AllTests {}
Related
I want to exclude those test classes which have ALL the categories mentioned in the section of the failsafe configuration.
Presently, I believe it excludes all test classes which have any one of the categories mentioned in the configuration.
<excludeGroups> Group1, Group2 </excludeGroups>
#Categories(Group1.class)
public class SampleTest {
}
I want SampleTest to run with the mentioned configuration, but it is NOT running.
I have a test suite which tests two different things in the same class. I have a before method that initialises some fields for the test methods to use. However, I have a group of test methods that uses the first set of field, and another group that uses the second, but not the first. I know it's possible to split the before action over different before methods, but is it also possible to specify which one runs before each test?
Concrete example:
#Before
public void before1() {...}
#Before
public void before2() {...}
#Test
public void test1() {
//Only before1 runs
}
#Test
public void test2() {
//Only before2 runs
}
This is a simple representation, but I have much more tests that use either of these befores.
Everything you've stated in your question is pointing to splitting up your tests into 2 separate classes. I am guessing that the two groups you have are testing distinct features of your code and may even have some commonality in the test names. Take all of the tests that require before1 into a test class and all the tests that require before2 into another test class. You can name these new test classes according to the grouping of behaviour you're testing.
For example if half of your tests are for success scenarios and half are testing failure scenarios, put these into classes named something like FooSucceedsTest and the failures into FooFailsTest.
There is no guarantee on the order of a #Before executing just as there's no guarantee on a #Test order of execution.
The solution is to do any setup a test is dependent on in the #Test itself and use the #Before for common setup before test execution.
I am using jUnit to manage integration tests for an application that accesses a database. Because setting up the test data is a time-consuming operation, I have been doing that in the #BeforeClass method, which is executed only once per test class (as opposed to the #Before method, which is run once per test method).
Now I want to try a few different permutations for the configuration of the data layer, running all of my tests on each different configuration. This seems like a natural use of the Parameterized test runner. Problem is, Parameterized supplies parameters to the class constructor, and the #BeforeClass method is abstract and is called before the class constructor.
A few questions,
Does Parameterized call the #BeforeClass method for each permutation of parameters, or does it only call once?
If the #BeforeClass method is called repeatedly, is there some way to access the parameter values from inside of it?
If none of these, what do people suggest as the best alternative approach to this problem?
I think you are going to need a custom test runner. I'm having the same issue you are having (needing to run the same tests using multiple, expensive configurations). You'd need a way to parameterize the set up, perhaps using #Parameter annotations similar to those used by the Parameterized runner but on static member fields instead of instance fields. The custom runner would have to find all static member fields with the #Parameter annotation and then run the test class (probably using the basic BlockJunit4ClassRunner) once per static #Parameter field. The #Parameter field should probably be a #ClassRule.
Andy on Software has done a good job of developing custom test runners, and he explains so pretty clearly in these blog posts here and here.
#BeforeClass is only called once in your example. Which makes sense given the name - before class!
If your tests require different data, there are two choices I can think of:
Set up that data in #Before so it is test specific
Group the tests that you want to run with the same data into separate test classes and use #BeforeClass for each one.
You can call this initialization logic in the constructor of your test class. Keep track of the last parameter used in a static variable. When it changes, set up the class for the new parameter.
I can't think of an equivalent for AfterClass.
This is an old question, but I just had to solve a probably similar problem. I went with the solution below for now, which essentially is an implementation of TREE's (updated) answer with using a generic abstract base class in order to avoid duplication whenever you need this mechanism.
Concrete tests would provide a #Parameters method that return an iterable of single-element arrays containing a Supplier< T > each. Those suppliers are then executed exactly once per actual input needed by the concrete test methods.
#RunWith(Parameterized.class)
public class AbstractBufferedInputTest<T> {
private static Object INPUT_BUFFER;
private static Object PROVIDER_OF_BUFFERED_INPUT;
private T currentInput;
#SuppressWarnings("unchecked")
public AbstractBufferedInputTest(Supplier<T> inputSuppler) {
if (PROVIDER_OF_BUFFERED_INPUT != inputSuppler) {
INPUT_BUFFER = inputSuppler.get();
PROVIDER_OF_BUFFERED_INPUT = inputSuppler;
}
currentInput = (T) INPUT_BUFFER;
}
/**
*
* #return the input to be used by test methods
*/
public T getCurrentInput() {
return currentInput;
}
}
You could do your initialization in a #Before method, writing to an instance variable but testing for null.
#RunWith(value = Parameterized.class)
public class BigThingTests {
private BigThing bigThing;
#Before
public void createBitThing() {
if (bigThing == null) {
bigThing = new BigThing();
}
}
...
}
A new instance of BigThingTests is created for each set of parameters, and bigThing is set to null with each new instance. The Parameterized runner is single-threaded, so you don't have to worry about multiple initializations.
Let say I have a test class called MyTest.
In it I have three tests.
public class MyTest {
AnObject object;
#Before
public void setup(){
object = new AnObject();
object.setSomeValue(aValue);
}
#Test
public void testMyFirstMethod(){
object.setAnotherValue(anotherValue);
// do some assertion to test that the functionality works
assertSomething(sometest);
}
#Test
public void testMySecondMethod(){
AValue val = object.getAnotherValue();
object.doSomethingElse(val);
// do some assertion to test that the functionality works
assertSomething(sometest);
}
Is there any way I can use the value of anotherValue, which is set with its setter in the first test, in the second test. I am using this for testing database functionality. When I create an object in the DB I want to get its GUID so I can use this to do updates and deletes in later test methods, without having to hardcode the GUID and therefore making it irrelevant for future use.
You are introducing a dependency between two tests. JUnit deliberately does not support dependency between tests, and you can't guarantee the order of execution (except for test classes in a test suite, see my answer to Has JUnit4 begun supporting ordering of test? Is it intentional?). So you really want to have dependencies between two test methods:
you have to use an intermediate static value
as Cedric suggests, use TestNG, which specifically supports dependencies
in this case, you can create a method to create the line, and call it from both methods.
I would personally prefer 3, because:
I get independent tests, and I can run just the second test (in Eclipse or such like)
In my teardown in the class, I can remove the line from the database, the cleanup. This means that whichever test I run, I always start off with the same (known) database state.
However, if your setup is really expensive, you can consider this to be an integration test and just accept the dependency, to save time.
You should use TestNG if you need this (and I agree it's fairly common in integration testing). TestNG uses the same instance to run your tests, so values stored in fields are preserved between tests, which is very useful when your objects are expensive to create (JUnit forces you to use statics to achieve the same effect, which should be avoided).
First off, make sure your #Test 's run in some kind of defined order
i.e. #FixMethodOrder(MethodSorters.NAME_ASCENDING)
In the example below, I'm assuming that test2 will run after test1
To share a variable between them, use a ThreadLocal (from java.lang).
Note that the scope of the ThreadLocal variable is to the thread, so if you are running multiple threads, each will have a copy of 'email' (the static in this case implies that its only global to the thread)
private static ThreadLocal<String> email = new ThreadLocal<String>();
#Test
public void test1 {
email.set("hchan#apache.org);
}
#Test
public void test2 {
System.out.println(email.get());
}
You should not do that. Tests are supposed to be able to run in random order. If you want to test things that depend on one value in the database, you can do that in the #Before code, so it's not all repeated for each test case.
I have found nice solution, just add Before annotation to the previous test!
private static String email = null;
#Before
#Test
public void test1 {
email = "test#google.com"
}
#Test
public void test2 {
System.out.println(email);
}
If you, like me, googled until here and the answer didn't serve to you, I'll just leave this: Use #BeforeEach
I am trying to see if there is a way to include "descriptive text" in my junit reports by way of javadocs. JUnit 4 doesnt seem to support the 'description' attribute for the #Test annotation like TestNG does.
So far from what I have researched there is only one tool out there called javadoc-junit (http://javadoc-junit.sourceforge.net/). However I could not get this to work since it seems to be incompatible with Junit 4.
What I want is some way to provide a sentence or two of text with my each test method in the JUnit report. JavaDoc is no good since the target audience will have to swtich between JavaDoc and the Junit Report to see documentation and/or test stats.
Anyone know of anything else I could use with minimal effort?
Best,
Ray J
In JUnit 5 there is a way to annotate every test with a #DisplayName. The declared test classes can have text, special characters and emojis.
The declared text on each test is visible by test runners and test reports.
The Javadoc says:
public #interface DisplayName
#DisplayName is used to declare a custom display name for the annotated test class or test method.
Display names are typically used for test reporting in IDEs and build tools and may contain spaces, special characters, and even emoji.
And the User Guide:
import org.junit.gen5.api.DisplayName;
import org.junit.gen5.api.Test;
#DisplayName("A special test case")
class DisplayNameDemo {
#Test
#DisplayName("Custom test name containing spaces")
void testWithDisplayNameContainingSpaces() {
}
#Test
#DisplayName("╯°□°)╯")
void testWithDisplayNameContainingSpecialCharacters() {
}
#Test
#DisplayName("😱")
void testWithDisplayNameContainingEmoji() {
}
}
There's also rather recent solution called Allure. That's a Java-based test execution report mainly based on adding supplementary annotations to the code. Existing annotations include:
custom description: #Description("A cool test")
grouping by features or stories: #Features({"feature1", "feature2"}), #Stories({"story1", "story2" })
marking methods executed inside test case as steps: #Step (works even for private methods)
attachments: #Attachment(name = "Page screenshot", type = "image/png")
See their wiki and example project for more details.
I don't put javadocs in JUnit tests. I usually make the name of the method descriptive enough so it's as good as or better than any comment I could come up with.
I could imagine, that the Framework for Integrated Tests (FIT) would be a nice and clean solution.
What does FIT do?
FIT is a framework that allows to write tests via a table in a Word document, a wiki table or an html table.
Every character outside of a table is ignored by FIT and let you enter documentation, description, requirements and so on.
How does on of these tables look like?
Imagine a function MyMath.square(int) that squares it's input parameter. You have to build a so called Fixture, being an adapter between your MyMath and the following table:
class.with.Fixture.Square
x square()
2 4
5 25
The first column describes input values, the second the expected result. If it's not equal, this field is marked as red.
How does a Fixture look like?
For the given example, this would be the correct fixture:
package class.with.Fixture // Must be the same as in the fist row of the table
public class Square extends Fixture {
public int x; // Must be the same as in the second row
public int square() { // Must be the same as in the second row
return MyMath.square(x);
}
}
Probably, you can use FIT for your requirements.
Feel free to comment my answer or edit your question for more information!