Running Android Tests setUp() method gets called multiple times - java

I am creating a test suite for my android application and have this setUp method
private static final String TAG_NAME = "TESTING_SUITE";
public TestingMusicDAO musicDAO;
public List<Song> songs;
public Instrumentation instr;
MusicService musicService;
#Override
public void setUp() throws Exception {
instr = this.getInstrumentation();
Log.d(TAG_NAME, "Setting up testing songs");
musicDAO = new TestingMusicDAO(instr.getContext());
musicService = new MusicServiceImpl(musicDAO);
musicDAO.getAllSongsFromFile();
songs = musicDAO.getAllSongs();
for(Song song : songs)
Log.d( TAG_NAME, song.toString() );
}
And then have these tests which are created by a python tool from a text file
public void test1() {
List<Song> testPlaylist;
String testArtist = ("The Beatles");
String actualArtist = ("TheBeatles");
testPlaylist = testingPlaySongsByKeyword(testArtist);
if(testPlaylist.isEmpty()){
fail("No Songs Were Found");
} else {
for( Song loopsongs : testPlaylist){
if (!(loopsongs.getArtist().equals(actualArtist))){
fail("Song Doesnt Contain the artist" + actualArtist + "... Contains ->" + loopsongs.getArtist());
}
}
}
}
and every time one of these gets called the musicDAO is regenerated. How can I stop the setup method from being called

You don't. The design of JUnit is that setUp() and tearDown() are done once per test. If you want it done per class, do it in the constructor. Just make sure that you don't alter anything inside the classes. The reason for doing it once per test is to make sure all tests start with the same data.

You could use #BeforeClass and #AfterClass annotations from JUnit.
#BeforeClass
public static void test_setUp_Once(){
// Code which you want to be executed only once
createDb();
}
#AfterClass
public static void test_tearDown_Once(){
// Code which you want to be executed only once
deleteDb();
}
Note: You need to declare these methods static to work properly.

I had the same basic problem. I want to be able to test the structure of my database, so I create it in the setUp method and delete it in the tearDown. Using the constructor wouldn't solve my need to delete the database once all my tests are executed, so I used some reentrant logic:
static int testsExecutedSoFar = 0;
static boolean isFirstRun = true;
#Override
protected void setUp() throws Exception {
if(isFirstRun){
createDb();
isFirstRun = false;
}
}
#Override
protected void tearDown() throws Exception{
testsExecutedSoFar++;
if (testsExecutedSoFar == totalNumberOfTestCases())
deleteDb();
}
private int totalNumberOfTestCases() {
return countTestCases()+1; //have to add one for testandroidtestcasesetupproperly added by AndroidTestCase
}
The fields have to be static since JUnit creates a new instance of the class for each run. The magic 1 had to be added since AndroidTestCase adds it's own test (testandroidtestcasesetupproperly) to the test suite but it doesn't count towards the number returned by countTestCases().
A bit on the ugly side, but it did the trick.

Related

Junit Test Bool Value

Hello Every One I Have This Method Which it Checks if the Input String Is Numbers only And Its Return True Or False
I Want To Make A Junit Test For this method and Actually I Don't know how to test Method Like This Can Any One Help And Thank You All.
My Method:
private Boolean Check_Ean(String EAN_Ch)
{
Long EAN;
try
{
EAN = Long.parseLong(EAN_Ch);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
First you need to create a class in the test folder(located at the same path as main). Then you need to use their annotations to or either Prepare the information, Test and Destroy the information(usefull when you have DB connection opens or streams):
public class TestClass {
#Before
public void setup() {
//prepare information
}
#Test
public void testCheck_Ean() {
boolean result = Check_Ean(...);
Assert.assertTrue(result);
}
#After
public void destroy() {
//if you need to "destroy" some info
}
}
tester = new CLASS_NAME();
assertTrue(tester.Check_Ean("5");
assertFalse(tester.Check_Ean("this is noot a Long");
You might be overthinking it. Also the Check_Ean method maybe could be static if you pass the Ean as a parameter rather than getting a class variable.

Testing class that insert, update and delete from the db

I have class that has 3 methods: insert, update and delete from the db.
In order to test it in the insert test method I need to use the insert method and after I insert i need to delete what I inserted, but in order to delete I should use the delete method that I also want to test so it didn't make sense to me that I need to use them and also test them.
I hope you understand my problem. Thanks in advance!
You must decide what you want to test. That was you describe, it is an integration test. By a “real” unitTest, you test only your method, and not the System method and not the database.
If you want a unitTest, you have several options. For Example, you work with interfaces and catch your statement before it comes to the database.
Edit 1 - one possibility to implement unit test with interfaces:
You need one interface that implements the method these go to the backend system:
public interface IDatabase{
public returnValue insert(yourParam);
public int update(yourParam);
}
Then you implement your method with the real functions in a class:
public class Database implements IDatabase {
#Override
public returnValue insert(yourParam) {
// do something
return null;
}
#Override
public int update(yourParam){
// do something
return 0;
}
}
This class you call in the main class:
/**
* The real class to do what you want to do.
*/
public class RealClass {
private IDatabase dbInstance = null;
private IDatabase getDbInstance() {
if (dbInstance == null) {
dbInstance = new Database();
}
return dbInstance;
}
protected void setDbInstance(IDatabase dataBase) {
dbInstance = dataBase;
}
public static void main(String[] args) {
getDbInstance().insert(yourParam);
}
}
For the unit test you implement the interface again:
public class UnitTest implements IDatabase {
#Override
public returnValue insert(yourParam) {
// Here can you test your statement and manipulate the return value
return null;
}
#Override
public int update(yourParam){
if (yourParam.containsValue(value1)) {
assertEquals("yourStatement", yourParam);
return 1;
}else if (yourParam.containsValue(value2)) {
assertEquals("yourStatement2", yourParam);
return 5;
}else{
assertTrue(false,"unknown Statement")
}
}
#Test
public void yourTest(){
RealClass.setDbInstance(this);
//Test something
}
}
This is time-consuming to implement, but with this, you are independent from the backend system and you can call the unittest every time without a database.
By default, the order of test methods is not warrantied in JUnit. Nevertheless, as of JUnit 4.11, you can order by the test name, as follows:
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Test1 {
#Test
public void aInsert() {
System.out.println("first INSERT");
}
#Test
public void bUpdate() throws Exception {
System.out.println("second UPDATE");
}
#Test
public void cDelete() throws Exception {
System.out.println("third DELETE");
}
}

Mocking a DAO in Mockito

I'm just getting into testing of code. I have done unit tests before but haven't really isolated them. So they were more like integration test (indirectly). I want to give Mockito a try and I have added it to my Intellij IDE.
But I have no idea of how to actually implement mocking at all. There are examples on their website but I just can't wrap my head around the concept of mocking. I know that one uses mocking to isolate the unit testing to ensure that the errors are in the unit itself and not in a dependency.
I wrote the following:
#Test
public void testChangeMemberReturnsTrue() throws Exception {
Member tempMem = new Member();
tempMem.setMemberFirstName("Swagrid");
tempMem.setMemberLastName("McLovin");
tempMem.setMemberID("SM666");
SQLDUMMY.saveMember(tempMem); //Save member to dummy DB.
Member checkMem = new Member();
ArrayList<Member> memArr = SQLDUMMY.getAllMembers();
for (Member m : memArr) { // Look through all saved members
if (m.equals(tempMem)) { // If match, save to checkMem
checkMem = m;
}
}
assertTrue(tempMem.equals(checkMem)); // Make sure they are really equal.
String newfirstname = "Darius";
String newlastname = "DunkMaster";
assertTrue(memhandling.changeMember(tempMem, newfirstname, newlastname));
}
And here is the actual method:
public boolean changeMember(Member mem, String n1, String n2) {
try {
ArrayList<Member> memArr = SQLDUMMY.getAllMembers();
for (Member m : memArr) {
if (m.equals(mem)) {
m.setMemberFirstName(n1);
m.setMemberLastName(n2);
m.setMemberID(ensureUniqueID(m, m.getMemberID())); //Just a method call to another method in the same class to ensure ID uniqueness.
return true;
}
else {
return false;
}
}
}
catch (Exception e) {
System.out.println("Error4.");
}
return false;
}
I'd like to mock the SQLDUMMY (Which I created just to see if my tests would pass at all, which they do.) The SQLDUMMY class looks like this:
public class SQLDUMMY {
private static ArrayList<Member> memberList = new ArrayList<>();
private static ArrayList<Ship> shipList = new ArrayList<>();
public static ArrayList<Member> getAllMembers() {
return memberList;
}
public static void saveMember(Member m) {
memberList.add(m);
}
public static void deleteMember(Member memIn) {
memberList.remove(memIn);
}
public static void saveShip(Ship newShip) {
shipList.add(newShip);
}
public static ArrayList<Ship> getAllShips() {
return shipList;
}
public static void deleteShip(Ship s) {
shipList.remove(s);
}
}
It basically just consists of getters and add/remove for the ArrayLists that act as a contemporary DB storage.
Summary: How can I mock the SQLDUMMY class (DAO), so it is no longer a dependency for the Unit tests?
You need to read on how Mockito works.
The basic idea is that it extends you class and and overrides all methods and allows you to return what ever you want it too.
Syntax is :
SQLDummy sqlDummy = Mockito.mock(SQLDummy.class);
Mockito.when(sqlDummy.getAllShips()).thenReturn(new ArrayList< Ship >())

how to initialize common resource names in multiple junit4 test classes

I am creating a set of junit test classes ,all of which read from the same input data files.I created a test suite as below,but found that I would be replicating the filenames in each test class.
So, how do I do this without repeating the code..
#RunWith(Suite.class)
#SuiteClasses({SomeTests.class,someOtherTests.class})
public class AllTests{
}
-------------------
public class SomeTests{
private String[] allfiles;
public SomeTests() {
allfiles = new String[] {"data1.txt","data2.txt"};
}
#Test
public void testXX1(){
//
}
#Test
public void testXX2(){
//
}
}
public class someOtherTests{
private String[] allfiles;
public someOtherTests() {
allfiles = new String[] {"data1.txt","data2.txt"};
}
#Test
public void testYY(){
//
}
}
I thought I would have to make another class to provide the filenames as a String array..sothat the test classes can initialize the allfiles variable by calling the getFileNames() static method,combining this this with BeforeClass annotation
public class FileNames {
public static String[] getFileNames() {
return new String[]{"data1.txt","data2.txt"};
}
}
public class SomeTests{
private String[] allfiles;
public SomeTests() {
}
#BeforeClass
public void setUp(){
allfiles = FileNames.getFileNames();
}
#Test
public void testXX1(){
//
}
#Test
public void testXX2(){
//
}
}
but I am not sure that is the right way. This will require setUp() to be declared as static ,and that means I will have to make the instance variable allfiles static !
I think this is a common scenario in junit testing ..so can someone please tell me how to do this properly?
Use #Before instead of #BeforeClass, then your setUp() method need not be static.
However, unless you are going to modify your filename array in your tests, you could also create a base class for your tests and declare a protected constant with those names:
public class FileBasedTests {
protected static final String[] FILENAMES = {"data1.txt","data2.txt"}
}
public class SomeTests extends FileBasedTests {
...
}
If you really are concerned about each test having its own copy of those file names, you can write allFiles = FILENAMES.clone().

To find the number of test methods in a JUnit TestCase

Is there a way to know the number of test methods in a test case?
What I want to do is have a test case which tests several scenarios and for all these i would be doing the data setUp() only once. Similarly I would like to do the cleanup (tearDown()) once at the end of all the test methods.
The current approach i am using is to maintain a counter for the number of test methods that are present in the file and decrement them in the tearDown method and do the cleanup when the count reaches 0. But this counter needs to be taken care of whenever new test methods are added.
Instead of using setup/teardown you should probably use methods annotated with #BeforeClass and #AfterClass instead.
You can do this through #BeforeClass and #AfterClass in JUnit4:
http://junit.org/apidocs/org/junit/BeforeClass.html
Volker
Here is the piece of code I wrote to find all the test cases in my JUnit project. What it does is reads the files(under package mentioned in code) and using reflection APIs, finds the test cases with annotations "#Test" and also the ones which start with "test" but don't have the #Test annotation
public class TestCaseCount {
private static List<Class> getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes /* .toArray(new Class[classes.size()]) */;
}
private static List<Class> findClasses(File directory, String packageName)
throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.'
+ file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
public static void main(String args[]) {
ArrayList<Class> classes = new ArrayList<Class>();
try {
// Feature1 Test Cases
classes.addAll(TestCaseCount.getClasses("mypackage.feature1.tests"));
// Feature2 Test Cases
classes.addAll(TestCaseCount.getClasses("mypackage.feature2.tests1"));
classes.addAll(TestCaseCount.getClasses("mypackage.feature2.tests2"));
// Feature3 Test Cases
classes.addAll(TestCaseCount.getClasses("mypackage.feature3.tests"));
} catch (Exception e) {
e.printStackTrace();
}
int testcaseCount = 0;
for (Class cl : classes) {
System.out.println("Test Class Name : " + cl.getName());
Method[] methods = cl.getDeclaredMethods();
for (Method method : methods) {
Annotation[] annotations = method.getDeclaredAnnotations();
if (annotations.length == 0 && method.getName().startsWith("test")) {
testcaseCount++;
} else {
for (Annotation annotation : annotations) {
if (annotation.annotationType().toString()
.equals("interface org.junit.Test")) {
testcaseCount++;
}
}
}
}
}
System.out.println("Total Test Cases " + testcaseCount);
}
}
Short example for counting tests with #BeforeClass, #AfterClass and #Before.
public class CountTest {
static int count;
#BeforeClass
public static void beforeClass() {
count = 0;
}
#Before
public void countUp() {
count++;
}
#AfterClass
public static void printCount() {
System.out.println(count + " tests.");
}
#Test
public void test1() {
assertTrue(true);
}
// some more tests
Output will be, e.g.:
5 tests.
If you are using Junit4 and the suggestion given by others is the correct one. But if you using earlier version then use this technique to achieve what you want -
You can define a suite for all those tests for which you want to setup and teardown only once. Take a look at junit.extensions.TestSetup class. Instead of executing your test classes you need to then execute these suites.
A solution for junit 3 is to call a special setup method in every test which checks a static flag. if the flag is not set, run the global setup. If it is, skip the setup.
Make sure the global setup is properly synchronized if you want to run tests in parallel.
Using #Rules on TestWatcher you can take note of count and many other things like method name etc. You can override these methods and use .
#Override
public Statement apply(Statement base, Description description){
return super.apply(base, description);
}
#Override
protected void failed(Throwable e, Description description) {
failed.add(description);
LogUtil.error("[FAILED] "+description.getMethodName()+" [Test Failed]"+e.getMessage());
super.failed(e, description);
}
#Override
protected void finished(Description description) {
LogUtil.info("[FINISHED] "+description.getMethodName());
super.finished(description);
}
#Override
protected void skipped(AssumptionViolatedException e,Description description) {
LogUtil.error("[FAILED] Test Failed due to Assumption Voilation "+e.getMessage());
super.skipped(e,description);
}
#Override
protected void starting(Description description) {
LogUtil.info("-----------------------------------------------------------");
LogUtil.info("[STARTED] "+description.getMethodName());
super.starting(description);
}
#Override
protected void succeeded(Description description) {
passed.add(description);
LogUtil.info("[PASSED] "+description.getMethodName());
super.succeeded(description);
}
In your Junit Testcase Use
#Rule
public TestRule watcher = new TestWatcherChild();

Categories

Resources