1

I just started out with Java in school and have trouble with Junit tests. We were supposed to write a method that checks if a given arraylist is divisable by a given divisor. if the array is empty or the divisor is 0 it's supposed to return false. this is my code:

public class ArrayCheck {
/**
 * Tests all elements of the given array,
 * if they are divisible by the given divisor.
 *
 * @param arr
 *            array to be tested
 * @param divisor
 *              number by which all elements of the given array should be divisible
 * @return true if all elements are divisible by divisor
 */
public boolean allDivisibleBy(ArrayList<Integer> arr, int divisor) {
    //check if number is dividable or if number is 0
    for (int i=0; i<arr.size(); i++){
        if (arr.get(i) % divisor==0){
            return true;
        }   
            else if(arr.get(i)==0){
                return true;
            }
                //check if divisor is 0
                else if (divisor==0){
                    return false;
                }   
    }
    return false;
}
}

And here is my Junit-test so far. I understand, that i need to create different arraylists to test out my method, however i don't seem to fully understand how to implement these arrays and test them:

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;

import org.junit.Before;
import org.junit.Test;


public class ArrayCheckTest {

public ArrayCheck ArrayCheck = new ArrayCheck();

ArrayList<Integer> array1=new ArrayList<Integer>();
array1.add();



    @Test(timeout = 1000)
    public void testAllDivisibleBy() {

        ArrayCheck.allDivisibleBy(array1, 2);
    }
}

Any help in understanding Junit-test-implementation better would be appreciated! thanks!

Meowzen
  • 113
  • 1
  • 3
  • 15
  • 1
    you cannot have "flying code", put the code in a method. You might also want some assertions in your test code –  May 08 '16 at 09:42
  • Your 'allDivisibleBy()' logic is incorrect. It's not given expected output. – Geeth Lochana May 08 '16 at 10:21

3 Answers3

1

To test the complete method, your test class should be like as follows. You have to cover all the condition in your testing method. So you have to write several test methods to cover the testing method.

Corrected code:

public class ArrayCheck {
    /**
     * Tests all elements of the given array, if they are divisible by the given
     * divisor.
     *
     * @param arr
     *            array to be tested
     * @param divisor
     *            number by which all elements of the given array should be
     *            divisible
     * @return true if all elements are divisible by divisor
     */
    public boolean allDivisibleBy(ArrayList<Integer> arr, int divisor) {
        // check if number is dividable or if number is 0
        for (int i = 0; i < arr.size(); i++) {
            if (arr.get(i) != 0) {
                if (divisor == 0)
                    return false;
                else if (arr.get(i) % divisor != 0)
                    return false;
            }
        }
        return true;
    }
}

Test Class for corrected code:

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;

import org.junit.Before;
import org.junit.Test;

public class ArrayCheckTest {

    public ArrayCheck ArrayCheck = new ArrayCheck();
    ArrayList<Integer> array1;
    ArrayList<Integer> array2;

    @Before
    public void beforeTest() {
        array1 = new ArrayList<Integer>();
        array1.add(2);
        array1.add(4);
        array2 = new ArrayList<Integer>();
        array2.add(0);
    }

    @Test(timeout = 1000)
    public void testAllDivisibleBy() {
        // This only the check part of the code
        assertTrue(ArrayCheck.allDivisibleBy(array1, 2));
    }

    @Test(timeout = 1000)
    public void testAllNotDivisibleBy() {
        // This only the check part of the code
        assertFalse(ArrayCheck.allDivisibleBy(array1, 3));
    }

    @Test(timeout = 1000)
    public void testZeroDivisible() {
        // This only the check part of the code
        assertFalse(ArrayCheck.allDivisibleBy(array1, 0));
    }

    @Test(timeout = 1000)
    public void testZeroElement() {
        // This only the check part of the code
        assertTrue(ArrayCheck.allDivisibleBy(array2, 2));
    }
}
Geeth Lochana
  • 164
  • 13
  • thanks so much for your help! so the boolean method i used was not good because i did it the wrong way around? does it always have to return true in the end? i thought i could switch it around... – Meowzen May 08 '16 at 11:21
  • If the execution reach to the end, it return true, since all the items in the ArrayList are dividable by divisor. But midle of the code divisor == 0 or arr.get(i) % divisor != 0 satisfied when iterate the ArrayList it return false. – Geeth Lochana May 08 '16 at 11:25
1

I would try to explain you the framework JUnit.
I would like to start in a point where everybody agrees on that and gradual answer your question. Let P be a computer program that is designed to solve an algorithmically solvable problem.

P can be trivial(When you see P you can agrees that it´s correct). A trivial program could look like the following:

public static boolean invert(boolean proposition)
{
  return !proposition;
}

P can be but also complex. In this case there is a set of propositions that are logically related. You can use this propositions to prove that P is correct(A computer program is correct when for each input it delivers the desired result). That is what do people do from theoretical disciplines like classic Mathematics, Theoretical Computer Science, Computational Geometrie, ...

There is also a practical approach that can be used to demonstrate(not to prove) that P is correct in a specific context(note that a programm that is syntactically and semantically correct in macro computation could be considered as useless or unreliable in micro computation). This approach is known as Testing in Software Engineering(For more information see ISO/IEC/IEEE 29119-1)

The concept of Testing was used before the existence of test frameworks like JUnit, to demonstrate wether a given program is error free. For this purpose a set of new concepts constraints were introduced:

  • Production Code: is the code that is used in production and sometimes called Class Under Test(and it should be tested)
  • Test Code: is the code that will be used to test a Production Code
  • Constraint: A test code must not introduce additional business code
  • ...

Example of a Production Code:

public class Number 
{
    private int n;

    public Number(int n_passing)
    {
        n = n_passing;
    }

    public boolean isEven()
    {
        int rest = this.n % 2;
        boolean isEven = (rest == 0);

        if (isEven) {
            return true;
        }else {
            return false;
        }
    }
}

Example of a Test Code:

public class NumberTest 
{
    // Test case 1
    public static boolean testIsEven()
    {
        Number number = new Number(2);
        boolean expectedResult = true;
        boolean computedResult = number.isEven();

        return expectedResult == computedResult;
    }

    // Test case 2
    public static boolean testIsOdd()
    {
        Number number = new Number(1);
        boolean expectedResult = false;
        boolean computedResult = number.isEven();

        return expectedResult == computedResult;        
    }
}

Note that we need different Test Cases in order to demonstrate that the class Number is properly implemented.What means that we need Test Data, that leads to different results. The number of test cases that are necessary to achieve thorough Test Coverage can be determined using the Cyclomatic complexity(for further information see Cyclomatic Complexity)

Now, in order to run the test methods implemented in NumberTest we need an other class, let call it TestRunner, which could look like following:

public class TestRunner {

    public static void main(String[] args) 
    {
        System.out.println(NumberTest.testIsEven());
        System.out.println(NumberTest.testIsOdd());
    }
}

The problem of this approach is that when ever we change(add, remove, comment, ...) the test code NumberTest, we must change, save and recompile the TestRunner class. To test a class with a few number of test cases this problem is not important, but as soon as one deals we a project with a large number of test cases the approach became inefficient, what reduces the productivity.

A better approach would be creating a General Purpose Test Runner that does not need to be change when the test cases changed. This is the main idea behind test framework like JUnit, TestNG, ...

You can create your own Test framework using Java Annotations and Reflections.

Ayoub Falah
  • 484
  • 3
  • 19
0

You cannot do operations on arraylist is class area.

array1.add();

You would require to do like below. Also, as you have used generics you would require to give some int input.

@Test(timeout = 1000)
    public void testAllDivisibleBy() {
        array1.add(2);
        ArrayCheck.allDivisibleBy(array1, 2);
    }

Also, I would recommend that first go through basic concepts of Java, Java Collections and JUnit.

Links for Java Tutorial:

  1. http://www.tutorialspoint.com/java/index.htm
  2. http://www.javatpoint.com/java-tutorial

Links for Junit Tutorial:

  1. http://www.tutorialspoint.com/junit/index.htm
  2. http://www.javatpoint.com/junit-tutorial

Refer Below links for arraylist and generics:

  1. ArrayList or List declaration in Java
  2. What are Generics in Java?
  3. Java Generics: List, List<Object>, List<?>
Community
  • 1
  • 1
Pratiyush Kumar Singh
  • 1,977
  • 3
  • 19
  • 39