using invocationCount in testng tests with Java and Eclipse - java

I have a general test, call it
public void generalTest(boolean var1, boolean var2) {
if (var1) {
...
} else {
...
}
if (var2) {
...
} else {
...
}
}
I have a class level int countNumber initialized to 0; Then I do this
#Test(enabled = true, dataProvider = "getEmptyPhone", invocationCount = 4)
public void test(TextContext context) {
countNumber++;
boolean v1 = countNumber < 3;
boolean v2 = (countNumber % 2) == 0
generalTest(v1, v2);
}
countNumber increases each time so I get a combination of all booleans. The one thing is that the dataProvider is kind of complicated and it does a lot of soap messaging. Once I run it, I can use the same data in the other three tests, but in the above the data provider is called each time. Is there a way I can have it just do the data provider the first time? I know I could just have one test and put like for (boolean v : new boolean[] { true, false}), but that way if the test fails, the later ones will not be executed. Some tests could pass even if others didn't. So is there a way to do this?
I suppose it would also be too much to ask also if I could use the "description" keyword, and make countNumber be part of it so the test failure would show which iteration?

Related

Smoother way to exit a void recursive Java function

So I wrote this function that behaves like Knuth's Algorithm X. Just for illustration - the function requires a large matrix of possible rows among which it tries to select the combination of the ones that make up for a legitimate solution.
The thing is, once we found the solution, since its void, the function doesn't return anything and instead just backtracks up (which consequently means it prints out sudoku for every level in the recursion depth).
Any suggestions on how to end the function the moment the solution is found? I am currently using System.exit(0) but that isn't nice since the program then ends the moment you find the solution (so anything you want to do afterwards is impossible - for example run the function on array of sudokus and solve each one).
The code is here:
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
System.exit(0);
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
solve(solution, coverMatrix);
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
}
}
If I understand you correctly, you want to end recursion when you got the first solution. You can achieve this by having boolean return type for the method, and return true when you get first solution :.
public static boolean solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
return true;
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
boolean result = solve(solution, coverMatrix);
if(result == true) return result;//else continue
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
return false;
}
}
You can use the AtomicReference Class with a Boolean:
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix, AtomicReference<Boolean> test) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
test.set(true);//System.exit(0);
}
solve(solution, coverMatrix, test);
if(!test.get())
{
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
You can call your method like this(just initialize the Boolean to false):
public static void main(String[] args)
{
AtomicReference<Boolean> test1 = new AtomicReference<Boolean>();
test1.set(false);
solve(***, ***, test1);
}
You could misuse the concept of exceptions for that, although I would not recommend it.
First define a custom exception class.
public class SuccessException extends Exception {}
Throw an instance on success.
if (Arrays.equals(solvedCase, workCase)) {
drawSudoku(testOutput);
throw new SuccessException();
}
Call the function initially in a try block.
try {
solve(solution, coverMatrix);
} catch(SuccessException e) {
/* Solution found! */
}

Simplifying a method in java

I'm trying to create a simple method which I have below:
public void analyzeWithAnalytics(String data) {
for (int i = 0; i < VALUE; i++) {
if (data.equals("action1")) {
// call a method on a value
}
if (data.equals("action2")) {
// call a different method on a value
}
}
This is only a small snippet (I took a lot out of my code), but essentially I want to be able to call a specific method without testing multiple lines in my for loop for which method to call.
Is there a way for me to decide what value to call by declaring a variable at the very beginning, instead of doing so many 'if statement' tests?
OK, I have an ArrayList inside my class:
private List<Value> values;
The value object has 2 fields time and speed.
Depending on the string I pass (time or speed), I want to be able to call the specific method for that field without doing multiple string comparisons on what method I passed.
For example, I want to be able to call getSpeed() or getTime() without doing a string comparison each time I want to call it.
I just want to test it once.
Another one:
enum Action {
SPEED {
public void doSomething() {
// code
}
},
TIME {
public void doSomething() {
// code
}
};
public abstract void doSomething();
}
public void analyzeWithAnalytics(Action data) {
for (int i = 0; i < VALUE; i++) {
data.doSomething();
}
}
You can have a Map which maps the names (action1, action2, ...) to classes which common parent and one method. And make call as following:
map.getClass("action1").executeMethod();
Map<String, MethodClass> theMap = new Map<>();
interface MethodClass {
executeMethod();
}
and children:
class MethodClass1 implements MethodClass{...}
class MethodClass2 implements MethodClass{...}
Your goal is not really clear from your question. Do you want to:
avoid typing the many cases?
gain code readability?
improve performance?
In case you're after performance, don't optimize prematurely! Meaning, don't assume that this will be important for performance without checking that out first (preferably by profiling). Instead focus on readability and perhaps laziness. ;)
Anyway, you can avoid the many tests inside by simply checking data outside of the loop. But than you'd have to copy/paste the loop code several times. Doesn't make the method more beautiful...
I would also recommend using case instead of if. It improves readability a lot and also gives you a little performance. Especially since your original code didn't use if - elseif - ... which means all conditions are checked even after the first was true.
Do I get this right? data will not be changed in the loop? Then do this:
public void analyzeWithAnalytics(String data) {
if (data.equals("action1")) {
for (int i = 0; i < VALUE; i++) {
// call a method on a value
}
} else if (data.equals("action2")) {
for (int i = 0; i < VALUE; i++) {
// call a different method on a value
}
}
}
You can also switch on strings (Java 7) if you don't like ìf...
You could try something like this, it would reduce the amount of typing for sure:
public void analyzeWithAnalytics(String data) {
for (int i = 0; i < VALUE; i++) {
switch(data) {
case "action1": doSomething(); break;
case "action2": doSomething(); break;
}
}
}

How to capture JMockit expectation for known argument but fail if method is called with different argument

In JMockit how do you set an expectation for a method to be called 1 time for a known argument (or mocked argument) but set it to fail if it calls the method with a different argument.
i.e. I want to set an expectation for times = 1 where Arg = "XYZ" but times = 0 for any other call to method where Arg != "XYZ".
The ordering of these expectations only caused my test to fail. I did find a way to do this albeit to me it is rather cumbersome I feel, here is the code:
obj.getDTOs(anyString);
result = new Delegate() {
List<DTO> getDTOs(String testArg)
{
if (testArg.equals(expectedString)) {
return Collections.<DTO>emptyList();
} else {
throw new IllegalArgumentException();
}
}
};
result = Collections.<DTO>emptyList();
times = 1;
Is this the best way?
The following will work, although it could also be done with a Delegate:
static class Service {
List<?> getDTOs(String s) { return null; }
}
#Test
public void example(#Mocked final Service obj) {
new NonStrictExpectations() {{
obj.getDTOs("XYZ"); times = 1; // empty list is the default result
obj.getDTOs(withNotEqual("XYZ")); times = 0;
}};
assertEquals(0, obj.getDTOs("XYZ").size());
obj.getDTOs("abc"); // fails with "unexpected invocation"
}

Checking if assertions are enabled

You can enable/disable assert on the ClassLoader.
But how can you determine if they are already enabled?
(I want to take some code paths that perform expensive checks only if the JVM is invoked with assertions enabled.)
public static boolean areAssertsEnabled() {
boolean assertsEnabled = false;
assert assertsEnabled = true; // Intentional side effect!!!
return assertsEnabled;
}
boolean assertEnabled = false;
try {
assert false;
} catch (AssertionError e) {
assertEnabled = true;
}
ManagementFactory.getRuntimeMXBean().getInputArguments().contains("-ea");
The sibling answer is correct. But I question the utility and the generality of this approach. (Jump to “Alternative approach” for another way to deal with this problem.)
The simplest way for assertions to be enabled is if they are enabled for all classes.
-ea
or:
-enableassertions
In that case you can store that fact in one variable and use it throughout your program:
public class Main {
public static boolean assertsEnabled = false;
static {
assert assertsEnabled = true;
}
[…]
}
But say I have classes
Main, A, B, C
And:
-ea:Main -ea:A
I.e. assertions are only enabled for Main and A. The intent must thus be that assertions inside B and C shouldn’t be run.
Given this:
public class Main {
public static boolean assertsEnabled = false;
static {
assert assertsEnabled = true;
}
public static void main(String[] args) {
System.out.println("Hello from main()");
m();
assert A.print();
A.print2();
assert B.print();
B.print2();
assert C.print();
C.print2();
}
private static void m() {
if (assertsEnabled) {
System.out.println(" main() again (using static variable)");
}
}
}
It is clear how the print() methods will be handled: they will be run since -ea:Main. If -da:Main() then they will not be run.
m() will print the string since we know that assertsEnabled.
The print2() functions look like this:
// C
public static void print2() {
if (Main.assertsEnabled) {
System.out.println(" assert inside C (using variable from Main)");
}
}
Here, it is also clear what will happen: the program will print that string since -ea:Main and the way we initialized Main.assertsEnabled. But hold on: assertions are disabled for C (effectively -da:C). So is this really what we intended? Perhaps. Or perhaps we just used the static variable belonging to Main as it was convenient enough, and didn’t consider that this run in Main:
public static boolean assertsEnabled = false;
static {
assert assertsEnabled = true;
}
Will behave differently than the exact same code which would be copy-pasted into C.
So code that acts differently based on the assertion inclusion of other classes seems potentially confusing. Let’s instead just copy–paste this snippet into every class which uses assertions:
private static boolean assertsEnabled = false;
static {
assert assertsEnabled = true;
}
And use it like this:
if (assertsEnabled) {
// Error checking
}
But I think there is a more straightforward approach.
Alternative approach
OP:
I want to take some code paths that perform expensive checks only if the JVM is invoked with assertions enabled.
For any block of code X which is only supposed to be run if assertions are enabled
Make a static method x() with return type boolean
Just put return true to satisfy the type checker (could also be whatever you want to assert, but since you want to check if assertions are enabled and then run some code it seems that the checks are more involved than what one single boolean expression can conveniently achieve)
Put X inside the method body
Put assert in front of all invocations of x()
assert x();
[…]
private static boolean x() {
// X
}
For example:
private static boolean x() {
var setup = new Setup();
assert ...;
assert ...;
[more setup and preparation]
assert ...;
return true;
}
Interleaving regular code and assertion code
The “time how long this runs” problem: sometimes you have cross-cutting concerns. In this case, you might want to run some assertion-only code, then the regular code, and then finally the other part of the assertion-only code (which uses the first part).
The Java article on assertions covers how to approach this problem:
Occasionally it is necessary to save some data prior to performing a computation in order to check a postcondition. You can do this with two assert statements and a simple inner class that saves the state of one or more variables so they can be checked (or rechecked) after the computation. […]
Here’s a more simplified and hand-wavy example:
private static void doWork(Work work) {
ConsistencyCheck cc = null;
assert ((cc = new ConsistencyCheck(work)) != null);
doWorkInner(work);
assert cc.check(work);
}
The only overhead here (if it isn’t removed by the JIT as dead code) when running with assertions disabled would be to initialize an object to null, which shouldn’t be expensive.

Dequeue Testing

Could anyone tell me / explain how can I make a proper test of a Dequeue?
I have implemented a Priority Queue and in order to verify it I have done some junit tests.
I'm rather new to java so maybe I'm making some huge mistakes when trying to verify my implementation of a priority queue.
The test code :
#Test
public void testDequeue() throws MyException {
System.out.println("Dequeue");
PQueue q=new PQueue();
PQueue o=new PQueue();
q.Enqueue("abc", 1); // Enqueue with an object and a priority
q.Dequeue();
System.out.println(q.dim()); // to see if the dequeue worked
o.Enqueue("def", 2);
assertTrue(o.equals(q));
}
Pqueue Code:
public class PQueue<E> implements IPQueue<E>,Serializable{
private int size,front,rear;
private LinkedList<ListNode> list;
public PQueue()
{
front=0;
rear=0;
list=new LinkedList<ListNode>();
}
public void Enqueue(E obj, int p) throws MyException
{
if (obj==null) throw new MyException("Did not enqueued");
if (rear==0)
{
front=rear=1;
list.add(new ListNode(obj, p));
}
else
{
rear++;
int x= list.size();
for(int i=0;i<x-1;++i)
{
if(list.get(i).GetPriority() < p) list.add(i, new ListNode(obj, p));
}
}
}
public E Dequeue() throws MyException
{
if(rear==0) throw new MyException("Cannot dequeue; queue is empty!");
rear--;
return (E) list.getLast();
}
public int IsEmpty()
{
if(rear==0)
return 1;
else
return 0;
}
public int IsFull()
{
if(rear-front+2>size)
return 1;
else
return 0;
}
public void MakeEmpty()
{
size=0;
}
public int dim()
{
return rear;
}
public LinkedList<ListNode> getList()
{
return list;
}
#Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if (!(obj instanceof PQueue)) {
return false;
}
PQueue p = (PQueue)obj;
return (obj==p);
}
}
Your tests should test all possiblities of how the code may react to inputs. It is usually helpful to think about the testcases prior of coding the actual code which shall be tested. (Search for 'Test Driven Development' for a interesting, more dogmatic view on this issue)
I just wrote 4 tests: 2 testing the regular behavior, 2 testing exceptional cases.
I usually create some 'instance' member which I used for testing, which reduces each unit test by one line where I would otherwise have to create an instance (less code, less work).
Do not test ListNode in the code (that should be tested in ListNodeTest).
My tests below assume that new ListNode(2,1).equals( new ListNode(2,1) ).
private final PQueue<Integer> instance = new PQueue<Integer>();
#Test
public void testDequeue() throws Exception
{
System.out.println( "Dequeue" );
instance.Enqueue( 2, 1 );
assertEquals( new ListNode<Integer>(2, 1), instance.Dequeue() );
}
#Test
public void testDequeue_DequeuedTwice() throws Exception
{
System.out.println( "Dequeue_DequeuedTwice" );
instance.Enqueue( 2, 1 );
instance.Enqueue( 3, 2 );
assertEquals( new ListNode<Integer>(2, 1), instance.Dequeue() );
}
#Test( expected=MyException.class)
public void testDequeue_Empty() throws Exception
{
System.out.println( "Dequeue_Empty" );
instance.Dequeue();
}
#Test( expected=MyException.class)
public void testDequeue_DequeuedTwice() throws Exception
{
System.out.println( "Dequeue_DequeuedTwice" );
instance.Enqueue( 2, 1 );
instance.Dequeue();
instance.Dequeue();
}
One point, you may define new ListNode<Integer>(2, 1) as a static final for the test. I did not. Maybe I would have if I had used it 3 times...
Some other notes:
Have a look at http://www.oracle.com/technetwork/java/codeconventions-135099.html#367. Method names in Java are supposed to start with a lowercase letter.
You may argue that I myself violate that convention by introducing underscores '_' in the method names of testcase. I think thats handy, so I knowningly violate that convention for unit tests. Flame me for that.
Maybe you should also have a closer look at the junit FAQ http://junit.sourceforge.net/doc/faq/faq.htm.
You may think about changing the name of PQueue to PrioQueue or PriorityQueue.
And I would heavily recommend to test the equals() method thoroughly, in order to get from the code what you expect. Have a look what equals() is usually supposed to do. You are also missing a hashCode() method, which is commonly implemented when overwriting equals() yourself.
This doesn't make sense:
PQueue p = (PQueue)obj;
return (obj==p);
It's identical to:
return (p==p);
You might have meant:
return (this == p);
but that wouldn't really work either - that case is already dealt with by the first if clause.
If you want to compare the contents of the queues for equality, you'll need to iterate over them and check each of the items in both queues. Since you're using a linked list, you can do that directly:
return this.list.equals(p.list);

Categories