Hello at the risk of looking stupid I am having problem with Junit but I am at the stage where i do not care anymore.
I am trying to write a "simple" JUnit test for a Enum and I am almost tearing my hair out of frustration.
I get the famous error "cannot find symbol" when i try to call my methods in my public Enum. I feel like I am doing everything right and I do not understand what I am missing.
I have browsed Stackoverflow for quiet some time and have seen alot of people asking similar questions but I could not find any relevant solution to my problem.
I feel like this should be a reletive easy problem to spot if you are a experienced programmer but i have sat with this code for to long and cannot see the problem.
I would greatly appreciate if someone could point out the reason before I become bald...
// EDIT 1: Added package in Enum
// EDIT 2: Copied same code to Eclipse and the method is visible and i can run the test. I assume this is not a syntax problem but a internal error with the editor which is Netbeans in my case.
Case closed i suppose.
// EDIT 3: Added Netbeans tag
Here is my Enum:
package chess.domain;
import java.util.stream.Stream;
public enum Position {
A8(1,8), B8(2,8), C8(3,8), D8(4,8), E8(5,8), F8(6,8), G8(7,8), H8(8,8),
A7(1,7), B7(2,7), C7(3,7), D7(4,7), E7(5,7), F7(6,7), G7(7,7), H7(8,7),
A6(1,6), B6(2,6), C6(3,6), D6(4,6), E6(5,6), F6(6,6), G6(7,6), H6(8,6),
A5(1,5), B5(2,5), C5(3,5), D5(4,5), E5(5,5), F5(6,5), G5(7,5), H5(8,5),
A4(1,4), B4(2,4), C4(3,4), D4(4,4), E4(5,4), F4(6,4), G4(7,4), H4(8,4),
A3(1,3), B3(2,3), C3(3,3), D3(4,3), E3(5,3), F3(6,3), G3(7,3), H3(8,3),
A2(1,2), B2(2,2), C2(3,2), D2(4,2), E2(5,2), F2(6,2), G2(7,2), H2(8,2),
A1(1,1), B1(2,1), C1(3,1), D1(4,1), E1(5,1), F1(6,1), G1(7,1), H1(8,1);
private final int COLUMN;
private final int ROW;
Position(int col, int row) {
this.COLUMN = col;
this.ROW = row;
}
public int getCOLUMN() {
return this.COLUMN;
}
public int getROW() {
return this.ROW;
}
public Stream<Position> getColumn(Position position){
return Stream.of(Position.values()).filter(pos -> (pos.getCOLUMN()) == position.getCOLUMN());
}
public Stream<Position> getRow(Position position){
return Stream.of(Position.values()).filter(pos -> (pos.getROW()) == position.getROW());
}
}
And here is my test:
package chess.domain;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class PositionTest {
public PositionTest() {
}
#BeforeAll
public static void setUpClass() {
}
#AfterAll
public static void tearDownClass() {
}
#BeforeEach
public void setUp() {
}
#AfterEach
public void tearDown() {
}
/**
* Test of getCOLUMN method, of class Position.
*/
#Test
public void testGetCOLUMN() {
int expectedColumn = 1;
int actualColumn = Position.A8.getCOLUMN(); // ERROR IS LOCATED HERE ON METHOD "getCOLUMN"
assertEquals(expectedColumn, actualColumn);
}
/**
* Test of getROW method, of class Position.
*/
#Test
public void testGetROW() {
int expectedRow = 1;
int actualRow = Position.H1.getROW(); // ERROR IS LOCATED HERE ON METHOD "getROW"
assertEquals(expectedRow, actualRow);
}
}
We are running Sonarqube 5.6.1 with the Java Plugin 4.1 and having some troubles using the Sonar rule S2699 (Test should include assertions).
Using this example test class
import mypackage.Citit1543Dummy;
import mypackage.Citit1543OtherDummy;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isIn;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.core.IsNot.not;
import static org.mockito.Matchers.notNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.junit.Assert.assertThat;
public class Citit1543Test {
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test1() {
assert true;
}
#Test
public void test2() {
Assert.assertTrue(1 > (2-3));
}
#Test
public void test3() {
Assert.assertFalse(1 > (100-1));
}
#Test
public void test4() {
Assert.assertThat("test", 1, is(1));
}
#Test
public void test5() {
Assert.assertArrayEquals(new String[0], new String[0]);
}
#Test
public void test6() {
Assert.assertEquals(1 > 0, true);
}
#Test
public void test7() { // asserts in another method
test7asserts(1, 1);
}
private void test7asserts(int a, int b) {
Assert.assertTrue(a == b);
}
#Test
public void test8() {
test8asserts(1, 2);
}
private void test8asserts(int a, int b) {
Assert.assertNotSame(a, b);
}
#Test
public void test9() {
Citit1543Dummy dummy = new Citit1543Dummy();
dummy.otherDummy = mock(Citit1543OtherDummy.class);
dummy.doSomething();
verify(dummy.otherDummy, times(1)).doSomething();
}
#Test
public void test10() {
Citit1543Dummy dummy = new Citit1543Dummy();
dummy.otherDummy = mock(Citit1543OtherDummy.class);
dummy.doSomething();
test10verifies(dummy.otherDummy);
}
private void test10verifies(Citit1543OtherDummy otherDummy) {
verify(otherDummy, times(1)).doSomething();
}
#Test
public void test11() {
Assert.assertThat("test", "", not(1));
}
#Test
public void test12() {
Assert.assertThat("test", 1, lessThan(2));
}
#Test
public void test13() {
Long[] arr = new Long[] { 1L, 2L, 3L, 4L };
assertThat("Just testing", arr, is(new Long[] {
1L, 2L, 3L, 4L
}));
}
}
our Sonarqube instance flags the test cases test1 (assert statement not recognized), test7 (assert statements in another method), test8 (same) , test10 (Mockitos verify in another method), test11 and test13 as methods without assertions. I'm pretty sure that there are a lot more methods which aren't recognized (yes, unfortunately we use a bunch of different mocking/testing framework across our projects).
For now, we started to //NOSONAR whenever one of the asserts/verifies aren't recognized.
Is there an easy way to include these methods to be recognized as valid asserts?
Many of your stated issues are known and indeed (in some form of another) marked as FP:
test1: The current flow analysis ignores assert statements. See this post over at the groups.
The cases test7, test8 and test10 are related to the lack of not having cross-procedural analysis: They are valid cases but the current flow doesn't know that (ex.) test7assert is a valid assert statement for another method. See this post over at the groups.
Your other cases also produce false positives in the tests of S2699. I'd expect that once a SonarSource dev reads this topic that they'll create a ticket to resolve the cases in test11/13. But as I'm not a dev of them I can't guarantee that of course.
As to :
Is there an easy way to include these methods to be recognized as valid asserts?
No, the valid assertions are defined within the code of S2699 and are not a parameter. Some of your cases will require a more complex flow analysis whilst the last couple just seem to boil down to some missing definitions or too strict definitions, but I didn't deep-dive into the reasons why they produce FPs.
I mostly write Selenium WebDriver tests in Java but I recently had to work on some Selenium tests written in Python using nose. I noticed a great nose tool that generates separate test cases while iterating over a set of values (e.g. for testing every item in a drop-down list and getting a result entry for each).
http://swordstyle.com/func_test_tutorial/part_one/extra_generative_tests.html
Is there something similar that I could use in junit?
Sure, take a look at the JUNIT Data Provider library
From the docs:
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
#RunWith(DataProviderRunner.class)
public class DataProviderTest {
#DataProvider
public static Object[][] dataProviderAdd() {
// #formatter:off
return new Object[][] {
{ 0, 0, 0 },
{ 1, 1, 2 },
/* ... */
};
// #formatter:on
}
#Test
#UseDataProvider("dataProviderAdd")
public void testAdd(int a, int b, int expected) {
// Given:
// When:
int result = a + b;
// Then:
assertEquals(expected, result);
}
}
I need to create a custom function in Jmeter, and because of performance issues I can't use beanshell.
I wrote a java class following http://gabenell.blogspot.com/2010/01/custom-functions-for-jmeter.html and http://code4reference.com/2013/06/jmeter-custom-function-implementation/, but when I compile it I can't seem to get Jmeter to recognize it.
My class:
package custom.functions;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class Username extends AbstractFunction{
private static final List<String> desc = new LinkedList<String>();
private static final String KEY = "__Username";
private int number = 0;
static {
desc.add("Pass a random value to get a valid username for the system.");
}
public Username() {
super();
}
#Override
public synchronized String execute(SampleResult previousResult, Sampler currentSampler)
throws InvalidVariableException {
try {
return getValue(number);
} catch(Exception e){
throw new InvalidVariableException(e);
}
}
public String getValue(int number){
return "John-Smith";
}
#Override
public synchronized void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {
checkParameterCount(parameters, 1, 1);
Object[] values = parameters.toArray();
number = Integer.parseInt(((CompoundVariable) values[0]).execute().trim());
}
#Override
public String getReferenceKey() {
return KEY;
}
#Override
public List<String> getArgumentDesc() {
return desc;
}
}
When I run jar tf custom-functions.jar (to verify that the class file is in the jar):
META-INF/
META-INF/MANIFEST.MF
custom/
custom/functions/
custom/functions/Username.class
I placed the jar in my jmeter lib/ext directory and tried running jmeter by itself and with -Jsearch_paths=../lib/ext/custom-functions.jar, but either way when I open the function helper tool it's not listed, and a simple test plan to verify the function sends instead %24%7B__Username%281%29%7D.
Am I not putting the file in the right place? Is it named incorrectly?
You can put groovy-all.jar on the classpath of Jmeter, and then you will be able to run external .groovy scripts or you can add a JSR223-Groovy Sampler.
My problem was that I had compiled my class using Java 8 instead of Java 7, which was the runtime I was using for jmeter.
Instead of constantly creating identical debug configuraitons for my test cases, I would like to be able to simply save a few arguments common across all my Junit tests, right click on a specific test, then run that single run config. IE I would like a single debug configuration that can take as an argument the current selected test case instead of requiring me to manually specify it every time in the JUnit run configuration. My only options in the dialog appear to be either to specify a single test class or run all the tests in the project. As a result, Eclipse is littered with dozens of run configurations for all my test cases.
Instead of specifying a specific test class, I'd like it to specify a variable like ${container_loc} or ${resource_loc} for the class to run as in this question. Is there a variable in Eclipse that specifies the current selected Java class that I could place in the test class field in the dialog?
A specific example where this is useful is when running the Lucene unit tests. There's lots of arguments you can specify to customize the tests, some of which like -ea are required. Everytime I want to test a specific test case in Lucene in Eclipse, I have to manually setup these variables in the Eclipse debug config dialog :-/.
Have you looked at Parameterized Tests in JUnit? Here is an example:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
#RunWith(Parameterized.class)
public class ParamTest {
#Parameters(name = "{index}: fib({0})={1}")
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][] {
{ 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 }
});
}
private int input;
private int expected;
public ParamTest(int input, int expected) {
this.input = input;
this.expected = expected;
}
#Test
public void test() {
Assert.assertEquals(expected, input);
}
}
If you just want to run one test at a time you can use private variables as in:
public class MultipleTest {
private int x;
private int y;
public void test1(){
Assert.assertEquals(x, y);
}
public void test2(){
Assert.assertTrue(x >y);
}
public void args1(){
x=10; y=1;
}
public void args2(){
x=1;y=1;
}
public void args3(){
x=1;y=10;
}
#Test
public void testArgs11(){
args1();
test1();
}
#Test
public void testArgs21(){
args2();
test1();
}
#Test
public void testArgs31(){
args3();
test1();
}
#Test
public void testArgs12(){
args1();
test2();
}
#Test
public void testArgs22(){
args2();
test2();
}
#Test
public void testArgs32(){
args3();
test2();
}
}