I have simple Android application with some espresso tests.
I want to write some base class so all of my test classes will inherit its #beforeClass and #afterClass methods, but the problem is when I do it like code example below, JUnit doesn't see any tests at al. I got Empty test suite. message. What's the problem?
Code example:
public class RealmTest {
protected static Realm realm;
#BeforeClass
public static void beforeClass() {
realm = Realm.getDefaultInstance();
realm.setAutoRefresh(true);
}
#AfterClass
public static void afterClass() {
realm.close();
}
}
#RunWith(AndroidJUnit4.class)
public class MainActivityTest extends RealmTest {
#Rule
public IntentsTestRule<MainActivity> activityTestRule = new IntentsTestRule<>(MainActivity.class);
#Test
public void startedFine() {
assertNotNull(realm);
onView(withId(R.id.button)).perform(click());
intended(hasComponent(new ComponentName(getTargetContext(), EducationActivity.class)));
}
}
If I'll run all tests, tests from MainActivityTest won't run.
Thanks for your help, pls say if some additional info is needed.
Guessing: the JUnit environment is not looking for static methods. So maybe you simply drop that keyword from your base methods (guess you could keep your Realm static nonetheless; I assume you really only want one of those).
But then, another suggestion: don't use inheritance for test cases.
The point that makes test cases valuable to you is: they should quickly allow you to find and fix bugs in your production code.
But when your "setup" is hidden from your testcases - because things are not only happening in some #Before method ... but in a #Before method somewhere, in some different class ... well, that can seriously increase the time you will need to understand a failing testcase. Because: instead of just studying your test case, you find yourself digging around within test code in order to understand what exactly is happening besides the code in that failing test method itself!
Thus: be really careful to balancing "code duplication" versus "test case is easy to understand" aspects!
Related
I have a maven Java project in Intellij IDEA community. The TestNg version is very old i.e. 6.9.5 and I simply cannot update it. I have 6 TestNg test methods in a class. Only 5/6 of these methods use data provider methods, all of which are in one DataProvider class.
When I run the test class, only the method without data provider (say test_5) runs successfully. The others are marked as "test ignored". Moreover, when I comment or disable test_5, then all the other tests run. Can I make testng give a detailed reason for ignoring tests ?
Here is brief information about my project. I can't give the full code.
public class MyUtilityClass {
public class MyUtilityClass(){
//Load data from property files and initialize members, do other stuff.
}
}
public class BaseTest {
MyUtilityClass utilObj = new MyUtilityClass();
//do something with utilObj, provide common annotated methods for tests etc.
}
public class TestClass extends BaseTest {
#BeforeClass
public void beforeMyClass(){
//Get some data from this.utilObj and do other things also.
}
#Test(dataProvider = "test_1", dataProviderClass = MyDataProvider.class)
test_1(){}
#Test(dataProvider = "test_2", dataProviderClass = MyDataProvider.class)
test_2(){}
...
//test_5 was the only one without data provider.
test_5(){}
#Test(dataProvider = "test_6", dataProviderClass = MyDataProvider.class)
test_6(){}
}
public class MyDataProvider {
MyUtilityClass utilObj = new MyUtilityClass();
//do something with utilObj besides other things.
}
Your tests need to end in exactly the same environment in which they started.
You gave nary a clue as to what your code is like, but I can say that it is almost certainly either a database that is being written to and not reverted or an internal, persistent data structure that is being modified and not cleared.
If the tests go to the database, try enclosing the entire test in a transaction that you revert at the end of the test. If you can't do this, try mocking out the database.
If it's not the DB, look for an internal static somewhere, either a singleton pattern or a static collection contained in an object. Improve that stuff right out of your design and you should be okay.
I could give you more specific tips with code, but as is--that's about all I can tell you.
I solved my problem. Test_5 is the only test method which does not have a data provider. So, I provided a mock data provider method for it.
I am using TestNG with Selenium WebDriver, the framework that I use has one base class which has BeforeClass method and all the Suite classes extend from this base class and have overriden BeforeClass methods as shown.
public BaseClass{
#BeforeClass
public void preConditions{
//primary actions like opening browser and setting preferences
}
}
public TestSuiteClass extends BaseClass{
#BeforeClass
#Override
public void preConditions(){
super.preCnditions();
//specific preconditions required by test suite
}
}
The problem I am have is, if an overridden method is failing for any reason, all the test suits/cases gets skipped and entire test execution stops.
How to stop this from happening?
If something fails in #Before... annotated procedure the tests will be skipped instead of failing, because the problem is not with your test cases, but with the process before them. So it looks like your car cannot cross the river on a broken bridge, but it's not your car's fault.
If you really want to do some hacking about it, you can find ideas here!
You can find a way around this, but you need to consider if you realy want to do it. The idea of the method with #BeforeClass annotation is to set relevant data for the test (you even called it preConditions). If it fails, the test won't pass anyway.
One way to do it is to remove the #BeforeClass annotation and call the method from the test itself
public TestSuiteClass etends BaseClass {
public void customPreConditions() {
super.preCnditions();
}
#Test
publuc void someTest() {
customPreConditions();
// do the test
}
}
The test will continue even if customPreConditions() is not successful.
I'm currently having some memory problems with some unit tests in a fairly large project of mine. Throughout my hair pulling and research today, I have come to realize that it appears to be related to objects not always being cleaned up as fast as I think they should be cleaned up. I started researching "cleanup mockito" and "cleanup junit" and came across a few blogs and forum posts about how to use #Before and #After (as well as their *Class versions) to do intense things that you don't want being done with every unit test. This got me to thinking about Mockito's #Mock and #InjectMocks annotations.
Can someone please describe to me in detail how the class variables below are being handled in memory during a maven build? Will the objects be created before, during, or after unit tests? Are the objects immediately destroyed after the last unit tests completes? Should I be using #After to set all the class variables to null?
Thanks many times over. Here's a sample of a test case I may use:
#RunWith(MockitoJUnitRunner.class)
public class thisCustomTest {
#Mock
MyCustomSpringBean myCustomerSpringBean;
#InjectMocks
MyBeanToTest myBeanToTest;
#Before
public void config() {
MockitoAnnotations.initMocks(this);
}
#Test
public void someTest() {
//code here
}
}
Just to do a quick wrap-up / summary at the end, my main question is whether or not I should be utilizing something like #After to clean up class variables, or should I simply leave those for Java's normal scope garbage collection...
My idea of cleanup:
#After
public void cleanup() {
mockedClassVariable = null;
injectedVariable = null;
}
JUnit creates a new instance of your unit test class before running each test method. Once the instance is created, its #Before annotated method(s) is (are) executed. Then the test method is executed. Then, whatever happened in the test method (success, failure or error), the #After annotated method(s) is (are) run.
So, in this particular case, MockitoAnnotations.initMocks(this) is executed before each test method, which creates a new mock each time, a new MyBeanToTest each time, and injects the mock into the bean to test.
Those beans will be eligible for GC, along with the test instance which references them, after the test method execution. Setting them to null in the cleanup method doesn't serve any purpose.
I'm driving a suite of Selenium tests (actually WebDriver-backed Selenium) using JUnit 4.8.2. I'd like the tests to automatically take a screenshot of the browser as soon as the test fails an assertion. All the tests inherit from SeleniumBaseTestCase, and the majority then further inherit from from SeleniumBastTestCaseWithCompany (which uses #Before and #After methods to create and then clean up common test data via Selenium).
I've tried adding a subclass of TestWatchman as a #Rule in SeleniumBaseTestCase, overriding TestWatchman's failed method to take the screenshot. The trouble is that the #After methods cleaning up the test data are being run before TestWatchman's failed method is called, so the screenshots are all of the final step of the clean-up, not the test that failed.
Looking into it a little, it seems that TestWatchman's apply method just calls the passed Statement's evaluate method (the only exposed method), which calls the #After methods, leaving TestWatchman (or any other Rule) no chance to insert any code between the execution of the test and of the #After methods, as far as I can tell.
I've also seen approaches that create a custom Runner to alter the Statements created so that methods annotated with the custom #AfterFailure are run before #After methods (so the screenshot can be taken in such an #AfterFailure method), but this relies on overriding BlockJUnit4ClassRunner's withAfters method, which is deprecated and due to become private, according to the documentation, which suggests using Rules instead.
I've found another answer on SO about the #Rule lifecycle that makes it sound like this simply might not be possible in JUnit 4.8, but may be possible in JUnit 4.10. If that's correct then fair enough, I'd just like confirmation of that first.
Any thoughts on an elegant and future-proof way in which I can achieve what I want would be much appreciated!
You are right in your analysis, #Befores and #Afters are added to the list of Statements before any Rules. The #Before gets executed after the #Rule and the #After gets executed before the #Rule. How you fix this depends on how flexible you can be with SeleniumBaseTestCaseWithCompany.
The easiest way would be to remove your #Before/#After methods and replace them with an ExternalResource. This could look something like:
public class BeforeAfterTest {
#Rule public TestRule rule = new ExternalResource() {
protected void before() throws Throwable { System.out.println("externalResource before"); }
protected void after() { System.out.println("externalResource after"); }
};
#Test public void testHere() { System.out.println("testHere"); }
}
this gives:
externalResource before
testHere
externalResource after
This field can be put into your base class, so it gets inherited/overridden. Your problem with ordering between #After and your rules then goes away, because you can order your rules how you like, using #RuleChain (in 4.10, not 4.8).
If you can't change SeleniumBaseTestCaseWithCompany, then you can extend BlockJUnit4ClassRunner, but don't override withAfters, but override BlockJUnit4ClassRunner#methodBlock(). You can then call super.methodBlock, and reorder the Statements as necessary[*].
[*]You could just copy the code, and reorder the lines, but withRules is private and therefore not callable from a subclass.
The selenium tests I'm gonna be doing are basically based on three main steps, with different parameters. These parameters are passed in from a text file to the test. this allows easy completion of a test such as create three of "X" without writing the code to do the create three times in one test.
Imagine i have a test involving creating two of "X" and one of "Y". CreateX and CreateY are already defined in separate tests. Is there a nice way of calling the code contained in createX and createY from say, Test1?
I tried creating a class with the creates as seperate methods, but got errors on all the selenium.-anything-, ie every damn line. it goes away if i extend seleneseTestCase, but it seems that my other test classes wont import from a class that extends seleneseTestCase. I'm probably doing something idiotic but i might as well ask!
EDIT:
well for example, its gonna be the same setUp method for every test, so id like to only write that once... instead of a few hundred times...
public void ready() throws Exception
{
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "https://localhost:9443/");
selenium.start();
selenium.setSpeed("1000");
selenium.setTimeout("999999");
selenium.windowMaximize();
}
thats gonna be used EVERYWHERE.
its in a class called reuseable. Id like to just call reuseable.ready(); from the tests SetUp... but it wont let me....
public class ExampleTest {
#Before
public void setup() {
System.out.println("setup");
}
public void someSharedFunction() {
System.out.println("shared function");
}
#Test
public void test1() {
System.out.println("test1");
someSharedFunction();
}
#Test
public void test2() {
System.out.println("test2");
someSharedFunction();
}
}
The contents of the function after the #Before annotation is what will be executed before every test. someSharedFunction() is an example of a 'reusable' function. The code above will output the following:
setup
test1
shared function
setup
test2
shared function
I would recommend using JUnit and trying out some of the tutorials on junit.org. The problem you have described can be fixed using the #Before annotation on a method that performs this setup in a super class of your tests