Code testing for beginners - how to do? - java

Lets say that I have a lot of nested loops (3-4 levels) in a java method and each of these loops can have some if-else blocks. How can I check if all these things are working properly ? I am looking for a logical way to test this instead of using a brute force approach like substituting illegal values.
EDIT:
Can you also suggest some good testing books for beginners ?

The way I've always been taught basic testing is to handle around edge cases as much as possible.
For example, if you are checking the condition that variable i is between 0 and 10 if(i>0 &&i<10), what I would naturally test is a few values that make the test condition true, preferably near the edges, then a few on the edges that are a combination of true and false, and finally cases that are way out of bounds. With the aforementioned condition, I'd test 1,5 ,9, 0, 10, -1, 11, then finally an extremely large integer, both positive and negative.
This sort of goes against the "not substituting illegal values)", but I feel that you have to do that in order to ensure that your conditions fail properly.

EMMA is a code coverage tool. You run your unittests under EMMA and it will produce an HTML report with colorized source code showing which lines were reached and which were not. Based on that you can add tests to make sure you're testing all the various branches.
Each if/then in your code contains a boolean sub-expression as is the sub-expression used in a loop to decide whether to enter/rerun the loop. Predicate coverage should tell give you a good idea how thorough your tests are.
Wikipedia explains predicate coverage
Condition coverage (or predicate coverage) - Has each boolean sub-expression evaluated both to true and false? This does not necessarily imply decision coverage.

I believe that using debug is easiest way to find the mistake. You can find a full explanation about debug at this link: http://www.ibm.com/developerworks/library/os-ecbug/.
Also you can use this link: http://webster.cs.washington.edu:8080/practiceit/ for practising.

for example find input which will go through each of those loops with some values. then find input which will go through each branch of the if's. Then find input which will go through the loops with large or small or illegal values.

Set some input and output data. Make the calculations yourself.
Create a class to check if the output values match the ones you separately calculated.
Example:
input: Array(3,4,5,6);
output (sum of odd numbers) : 8
class TestClass{
//test case
//here you keep changing the array (extreme values, null etc..
public void test1(){
int[] anArray=new int[4];
anArray[0] = 3;
anArray[1] = 4;
anArray[2] = 5;
anArray[3] = 6;
int s=Calculator.oddSum(x);
if (s==8)
System.out.println("Passed");
else
System.out.println("Failed");
}
public static void main(){
TestClass t=new TestClass();
t.test1();
}
}

Related

How to handle the case that a single simple test case will drive the whole implementation?

When I learn "Test Driven Development", I found an interesting case from the book "The Productive Programmer":
You need to find all factors of a "complete number". A complete number is the sum of all its factors (except the one which equals to the number itself) is equal to the number. So 6 is the minimal complete number, and its factors are 1, 2, 3.
If I want to TDD, first I want to test an simplest test case:
#Test public void completeNumber6() {
CompleteNumber completeNumber = new CompleteNumber(6)
assertEquals(completeNumber.findFactors(), new Int[] {1,2,3});
}
But ! The problem is this simplest case will driven all the implementation of findFactors(), which seems too much for me.
The author gives some suggestions, we can split the requirements into several steps:
check if number is the factor of another one
provide a way to collect some factors into a collection
check each smaller number to see if it's the factor of the given number, collect them
check if the sum of the collected factor equal to the given number
And we can TDD the first 2 steps first:
#Test public void testIsFactor() {}
#Test public void testAddFactor() {}
So there will be 2 public (at least non-private) methods after that:
boolean isFactor(Int n1, Int n2)
void addFactor(Int factor)
The problem is these 2 methods should be private after the whole implementation, since they should only used by findFactors internally!
But if they are changed to private, what shall we do with the exsiting test cases for them?
The author suggests we can change them to private, and use Java refection API to get and test them. Sounds possible, but I'm not sure if it's a good practice to do so.
I also asked some friends, and they gave some other options:
Keep the methods isFactor and addFactor non private as is, that's acceptable
Extract a class FactorChecker and FactorCollector for the 2 methods
Change them to private, and delete the test cases since the functionality of them has been tested in the later test cases (for step 3 & 4)
I'm really puzzled now, which approach is the best practice of TDD?
Seems to me that the fact that the question states these are complete numbers is somewhat irrelevant. You can calculate the factors of any whole number. So given that I'd start with implementing findFactors(1) and then work my way up.
That makes this a slight variation on the classic Prime Factors Kata, the only difference being that you add a 1 to list of factors.

Java-Android-Process time in IF statement (real time code)

I have 2 codes snippets with the same condition:
boolean A =true;
boolean B =true;
very simple.
But Which one of the 2 codes will be faster ,only in this case,not when one of them is false
first code:
if(A&&B){
doSomthing();
}
second code:
if(A){
if(B){
doSomthing();
}}
Remember: A and B are true.
I just modify and optimize my code that do real time rendering,and every millisecond could be big improvment in terms of very large arrays.
**I guess that if A=false, the second code will be faster. but if B=false the first will be faster?
more info: A and B in my case is just two conditions like:
(mNumber==5&&arr[j]!=19)
results after test it: with the conditions: A=true; and B=true; there is no really different between the 2 codes( mixing results in term of nano seconds-kind of equels results)
The compiler is very likely to turn these into identical code. Even in "real-time" code, don't code things like this based on what you think will be fastest; write clear code, and then profile if you think there's a problem.
In this case, if(a & b) is significantly clearer, so use that. (It will also be the faster option if the compiler generates different code, because there's only one comparison and jump needed. Note that this is different from the canonical handling of a && b.)
Edit: It looks like you edited your question to change the condition from & to &&. Short-circuiting is a good idea when the arguments are expensive to evaluate, but if they're really both boolean values, ANDing them together is almost always cheaper.

Can Java skip .toUpperCase() on literal string constants already in upper case?

I have a .toUpperCase() happening in a tight loop and have profiled and shown it is impacting application performance. Annoying thing is it's being called on strings already in capital letters. I'm considering just dropping the call to .toUpperCase() but this makes my code less safe for future use.
This level of Java performance optimization is past my experience thus far. Is there any way to do a pre-compilation, set an annotation, etc. to skip the call to toUpperCase on already upper case strings?
What you need to do if you can is call .toUpperCase() on the string once, and store it so that when you go through the loop you won't have to do it each time.
I don't believe there is a pre-compilation situation - you can't know in advance what data the code will be handling. If anyone can correct me on this, it's be pretty awesome.
If you post some example code, I'd be able to help a lot more - it really depends on what kind of access you have to the data before you get to the loop. If your loop is actually doing the data access (e.g., reading from a file) and you don't have control over where those files come from, your hands are a lot more tied than if the data is hardcoded.
Any many cases there's an easy answer, but in some, there's not much you can do.
You can try equalsIgnoreCase, too. It doesn't make a new string.
No you cannot do this using an annotation or pre-compilation because your input is given during the runtime and the annotation and pre-compilation are compile time constructions.
If you would have known the input in advance then you could simply convert it to uppercase before running the application, i.e. before you compile your application.
Note that there are many ways to optimize string handling but without more information we cannot give you any tailor made solution.
You can write a simple function isUpperCase(String) and call it before calling toUpperCase():
if (!isUpperCase(s)) {
s = s.toUpperCase()
}
It might be not significantly faster but at least this way less garbage will be created. If a majority of the strings in your input are already upper case this is very valid optimization.
isUpperCase function will look roughly like this:
boolean isUpperCase(String s) {
for (int i = 0; i < s.length; i++) {
if (Character.isLowerCase(s.charAt(i)) {
return false;
}
}
return true;
}
you need to do an if statement that conditions those letters out of it. the ideas good just have a condition. Then work with ascii codes so convert it using (int) then find the ascii numbers for uppercase which i have no idea what it is, and then continue saying if ascii whatever is true then ignore this section or if its for specific letters in a line then ignore it for charAt(i)
sorry its a rough explanation

Java Assert statement usage, exam certification 1Z0-851

I am studing for 1Z0-851 Oracla Java SE 1.6 Certification and I saw this question:
I marked the first alternative as the correct one and failed! "All of the assert statements are used appropriately" and the answer says that the first one assert(x > 0); is incorrect.. the question is why?
The correct answer is this
Appropriate and inappropriate use of assertions
You can place an assertion at any location that you don't expect to be reached normally.
Assertions can be used to validate the parameters passed to a private method. However,
assertions should not be used to validate parameters passed to public methods because a
public method must check its arguments regardless of whether assertions are enabled or
not. However, you can test postconditions with assertions in both public and non-public
methods. Also, assertions should not change the state of a program in any manner.
Src: http://www.freejavaguide.com/java-scjp-part1.pdf
Line 12 is redundant.
if you remove it, the assertion on line 15 will cover the case where x <= 0
To be honest its a strangely worded question but that is all I can see. I am not sure what is meant by appropriately
If you read just the first assert statement -- which should be interpreted as a "precondition" because of its position --, it implies that the function should work properly with any positive int value, which is not true. Therefore, that assertion is misleading.
Starting by go2, it is easy to understand the assert.
The method does nothing, it just asserts your expectation, that x < 0.
The go method, on the other hand, has a switch.
It is good practice to assert false on the default clause, if you absolutely do not expect your program to fall under this clause, ie, under normal circumstances, one of the cases has to be correct.
The only case on the switch expects x to be exactly 2.
So, to sum up, you don't expect x to be greater than 0, as the first assertion says, you expect x to be 2 and nothing else. Thus, the assertion is not used appropriately.
However, as Jeff noted, the case has no break, which means the default will always be executed, leading, in every scenario, to assert false.
Conclusion: The go method should always result in an error, making assert false properly used, while assert x > 0 isn't correct at all.

Why should I use Hamcrest-Matcher and assertThat() instead of traditional assertXXX()-Methods

When I look at the examples in the Assert class JavaDoc
assertThat("Help! Integers don't work", 0, is(1)); // fails:
// failure message:
// Help! Integers don't work
// expected: is <1>
// got value: <0>
assertThat("Zero is one", 0, is(not(1))) // passes
I dont see a big advantage over, let's say, assertEquals( 0, 1 ).
It's nice maybe for the messages if the constructs get more complicated but do you see more advantages? Readability?
There's no big advantage for those cases where an assertFoo exists that exactly matches your intent. In those cases they behave almost the same.
But when you come to checks that are somewhat more complex, then the advantage becomes more visible:
val foo = List.of("someValue");
assertTrue(foo.contains("someValue") && foo.contains("anotherValue"));
Expected: is <true>
but: was <false>
vs.
val foo = List.of("someValue");
assertThat(foo, containsInAnyOrder("someValue", "anotherValue"));
Expected: iterable with items ["someValue", "anotherValue"] in any order
but: no item matches: "anotherValue" in ["someValue"]
One can discuss which one of those is easier to read, but once the assert fails, you'll get a good error message from assertThat, but only a very minimal amount of information from assertTrue.
The JUnit release notes for version 4.4 (where it was introduced) state four advantages :
More readable and typeable: this syntax allows you to think in terms of subject, verb, object (assert "x is 3") rather than assertEquals, which uses verb, object, subject (assert "equals 3 x")
Combinations: any matcher statement s can be negated (not(s)), combined (either(s).or(t)), mapped to a collection (each(s)), or used in custom combinations (afterFiveSeconds(s))
Readable failure messages. (...)
Custom Matchers. By implementing the Matcher interface yourself, you can get all of the above benefits for your own custom assertions.
More detailed argumentation from the guy who created the new syntax : here.
Basically for increasing the readability of the code.
Besides hamcrest you can also use the fest assertions.
They have a few advantages over hamcrest such as:
they are more readable
(assertEquals(123, actual); // reads "assert equals 123 is actual" vs
assertThat(actual).isEqualTo(123); // reads "assert that actual is equal to 123")
they are discoverable (you can make autocompletion work with any IDE).
Some examples
import static org.fest.assertions.api.Assertions.*;
// common assertions
assertThat(yoda).isInstanceOf(Jedi.class);
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);
assertThat(frodo).isIn(fellowshipOfTheRing);
assertThat(sauron).isNotIn(fellowshipOfTheRing);
// String specific assertions
assertThat(frodo.getName()).startsWith("Fro").endsWith("do")
.isEqualToIgnoringCase("frodo");
// collection specific assertions
assertThat(fellowshipOfTheRing).hasSize(9)
.contains(frodo, sam)
.excludes(sauron);
// map specific assertions (One ring and elves ring bearers initialized before)
assertThat(ringBearers).hasSize(4)
.includes(entry(Ring.oneRing, frodo), entry(Ring.nenya, galadriel))
.excludes(entry(Ring.oneRing, aragorn));
October 17th, 2016 Update
Fest is not active anymore, use AssertJ instead.
A very basic justification is that it is hard to mess up the new syntax.
Suppose that a particular value, foo, should be 1 after a test.
assertEqual(1, foo);
--OR--
assertThat(foo, is(1));
With the first approach, it is very easy to forget the correct order, and type it backwards. Then rather than saying that the test failed because it expected 1 and got 2, the message is backwards. Not a problem when the test passes, but can lead to confusion when the test fails.
With the second version, it is almost impossible to make this mistake.
Example:
assertThat(5 , allOf(greaterThan(1),lessThan(3)));
// java.lang.AssertionError:
// Expected: (a value greater than <1> and a value less than <3>)
// got: <5>
assertTrue("Number not between 1 and 3!", 1 < 5 && 5 < 3);
// java.lang.AssertionError: Number not between 1 and 3!
you can make your tests more particular
you get a more detailed Exception, if tests fail
easier to read the Test
btw: you can write Text in assertXXX too...
assertThat(frodo.getName()).isEqualTo("Frodo");
Is close to natural language.
Easier read, easier analyze code.
Programer spend more time to analyze code than write new one. So if code will be easy to analyze then developer should be more productive.
P.S.
Code should be as well-written book.
Self documented code.
there are advantages to assertThat over assertEquals -
1) more readable
2) more information on failure
3) compile time errors - rather than run time errors
4) flexibility with writing test conditions
5) portable - if you are using hamcrest - you can use jUnit or TestNG as the underlying framework.

Categories

Resources