Invoke a method after all tests run in JUnit - java

I want to create custom html report for test run in JUnit. Problem I have is releasing resources and closing tags after all tests are done.
I keep one FileChannel opened for writing to report. Since it should be table with row for each test and there are hundreds of them, I don't want to open and close the channel for each test. Problem that appears here is tests organization - I have nested suites, so testRunFinished is not an option (refers to single suite, not all tests, and I saw this question). TestWatcher also will not help me, since it refers to single test only.
Tools used: maven 3.0.5, ff webdriver, junit 4.11.
I was considering two options:
1) opening and closing channel on each test run
2) overwriting finalize() to make it close the channel
None of them seems pretty... I've searched through many pages, but nobody seems to have the same problem I have.
Any prettier solutions?

Yes, see here (Before and After Suite execution hook in jUnit 4.x):
#RunWith(Suite.class)
#SuiteClasses({Test1.class, Test2.class})
public class TestSuite {
#BeforeClass
public static void setUp() {
System.out.println("setting up");
}
#AfterClass
public static void tearDown() {
System.out.println("tearing down");
}
}

Related

Junit - Override default behaviour to run tests only once, even if they are added several times (in different Suites)

For our usecase, as an example - we need to run a JUnit test, even if it is added multiple times within a Test Suite, without being skipped.
Currently we notice that JUnit test runner skips a Test with the same name, if it finds the test somewhere else within a Test Suite. Here is an example screenshot to show test "Case_A" within "Procedure_A" being skipped within a Test Suite -
Could this behaviour be overriden, if so could someone point us in the right direction?
I did some research arround this problem.
Simple setting - one Test "TestCase_A" and one Suite "TestProcedure_A" that runs the TestCase_A twice :
public class TestCase_A {
#Test
public void test() throws Exception {
System.out.println("Case_A RUN");
Assert.assertTrue(true);
}
}
#RunWith(Suite.class)
#Suite.SuiteClasses({ TestCase_A.class, TestCase_A.class })
#SuppressWarnings("all")
public class TestProcedure_A {
}
I run the test Suite using Eclipse and maven.
Finding: The sysout statement actually shows, that the TestCase_A runs twice!
Therefore, the Eclispe View is misleading. Test are run multiple times - the tree also reflects this. However, the status of the actual single calls is not displayed properly in the Eclispe Junit View.
I presume the view is based on the junit.runner.TestRunListener. It probably worth looking into that.

JUnit: Is there any difference between running a Suite, and running tests individually?

I am having a problem, one test class seems to be interfering with the other in my test suite.
I have a suite, which executes two classes, one is called MergeTestSuite.java (which is another Suite), and the other is called RecordTest.java.
RecordTest extends one class already tested by MergeTestSuite.java
I created another suite as follows:
#RunWith(Suite.class)
#Suite.SuiteClasses( {
MergeTestSuite.class,
RecordTest.class
})
public class CoreTestSuite {
#BeforeClass
public static void install() throws Throwable {
RegistryUtils.cleanupResources();
}
}
Both MergeTestSuite.class and RecordTest.class run fine individually. If I run CoreTestSuite, the second test will fail, unless I remove MergeTestSuite.class from the list.
A Junit TestSuite provides extra features for multiple tests. For instance, you can control the order in which the tests run and you can also combine multiple test suites into another suite. I think this older doc from Junit 3.1.8 describes it best.

Exclude some JUnit tests from automated test suite

When writing code that interacts with external resources (such as using a web service or other network operation), I often structure the classes so that it can also be "stubbed" using a file or some other input method. So then I end up using the stubbed implementation to test other parts of the system and then one or two tests that specifically test calling the web service.
The problem is I don't want to be calling these external services either from Jenkins or when I run all of the tests for my project (e.g. "gradle test"). Some of the services have side effects, or may not be accessible to all developers.
Right now I just uncomment and then re-comment the #Test annotation on these particular test methods to enable and disable them. Enable it, run it manually to check it, then remember to comment it out again.
// Uncomment to test external service manually
//#Test
public void testSomethingExternal() {
Is there is a better way of doing this?
EDIT: For manual unit testing, I use Eclipse and am able to just right-click on the test method and do Run As -> JUnit test. But that doesn't work without the (uncommented) annotation.
I recommend using junit categories. See this blog for details : https://community.oracle.com/blogs/johnsmart/2010/04/25/grouping-tests-using-junit-categories-0.
Basically, you can annotate some tests as being in a special category and then you can set up a two test suites : one that runs the tests of that category and one that ignores tests in that category (but runs everything else)
#Category(IntegrationTests.class)
public class AccountIntegrationTest {
#Test
public void thisTestWillTakeSomeTime() {
...
}
#Test
public void thisTestWillTakeEvenLonger() {
....
}
}
you can even annotate individual tests"
public class AccountTest {
#Test
#Category(IntegrationTests.class)
public void thisTestWillTakeSomeTime() {
...
}
Anytime I see something manually getting turned on or off I cringe.
As far as I can see you use gradle and API for JUnit says that annotation #Ignore disables test. I will add gradle task which will add #Ignore for those tests.
If you're just wanting to disable tests for functionality that hasn't been written yet or otherwise manually disable some tests temporarily, you can use #Ignore; the tests will be skipped but still noted in the report.
If you are wanting something like Spring Profiles, where you can define rulesets for which tests get run when, you should either split up your tests into separate test cases or use a Filter.
You can use #Ignore annotation to prevent them from running automatically during test. If required, you may trigger such Ignored tests manually.
#Test
public void wantedTest() {
return checkMyFunction(10);
}
#Ignore
#Test
public void unwantedTest() {
return checkMyFunction(11);
}
In the above example, unwantedTest will be excluded.

Maven does not stop on error using selenium webdriver 2

I am sorry if this is already answered, I tried to find a solution and still not getting anything.
I am working in Eclipse and Selenium webdriver and running the code via MAVEN.
My problem is that Maven continues running forever if an error was found, Selenium driver is not closed until I close the browser's window.
I can do it manually if anything happens in local, but the problem is when I try to use Jenknins, If anything fails, Jenkins job is running until I stop it.
Can you please help me?
Thanks in advance.
The important thing is to call WebDriver.quit() as you finish testing.
Usually in JUnit, this usually means calling it in one of these places:
a method or class annotated with #After or #AfterClass,
a property or class annotated with #Rule or #ClassRule,
a RunListener class, via the testFinished() or testRunFinished() methods,
a suitable runner class or
static teardown code.
You should choose the opposite to wherever you create your driver object. If all your tests are Selenium WebDriver ones and if you intend to run them sequentially in a single browser window (I think that this is the most common situation for smallish projects), then a single RunListener can hide this code nicely. As an example:
public class WebDriverContext extends RunListener {
public static WebDriver DRIVER; // Pretending to be final
public void testRunStarted(Description descr) {
DRIVER = new FirefoxDriver();
}
public void testRunFinished(Result result) {
DRIVER.quit();
}
}
(Credit to the OP for this answer, in his comment above. He's apparently gone from SO now, so he's not going to be able to post his answer here. I've also expanded it a fair bit.)

A better way to run lots of Integration Tests using JUnit?

What is the best way run a lot of integration tests using JUnit?
I crudely discovered that the code below can run all the tests... but it has a massive flaw. The tearDown() method in each of those classes is not called until they have all been run.
public class RunIntegrationTests extends TestSuite {
public RunIntegrationTests(){
}
public static void main (String[] args){
TestRunner.run(testSuite());
}
public static Test testSuite(){
TestSuite result = new TestSuite();
result.addTest(new TestSuite(AgreementIntegrationTest.class));
result.addTest(new TestSuite(InterestedPartyIntegrationTest.class));
result.addTest(new TestSuite(WorkIntegrationTest.class));
// further tests omitted for readability
return result;
}
}
The classes being run connect to the database, load an object, and display it in a JFrame. I overrode the setVisible method to enable testing. On our build machine, the java vm runs out of memory when running the code above as the objects it has to load from the database are pretty large. If the tearDown() method was called after each class finished it would solve the memory problems.
Is there a better way to run them? I'm having to use JUnit 3.8.2 by the way - we're still on Java 1.4 :(
Not sure if this is the problem, but according to the JUnit Primer you should just add the tests directly, instead of using the TestSuite:
result.addTest(new AgreementIntegrationTest()));
result.addTest(new InterestedPartyIntegrationTest()));
result.addTest(new WorkIntegrationTest()));
That's very strange. setUp and tearDown should bookend the running of each test method, regardless of how the methods are bundled up into suites.
I typically do it slightly differently.
TestSuite suite = new TestSuite( "Suite for ..." ) ;
suite.addTestSuite( JUnit_A.class ) ;
suite.addTestSuite( JUnit_B.class ) ;
And I just verified that tearDown was indeed being called the correct number of times. But your method should work just as well.
Are you sure tearDown is properly specified -- e.g. it's not "teardown"? When you run one test class on its own, is tearDown properly called?

Categories

Resources