java 单独运行时测试通过,但整个测试类运行时不通过
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26561511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tests pass when run individually but not when the whole test class run
提问by Orestis
I have solved a topCoder problem for which all the tests pass when I run them on their own. Nonetheless when I run the whole test class some of them fail. Could you, please, help me identify the reason for this behaviour? Here is my class and my tests:
我已经解决了一个 topCoder 问题,当我自己运行它们时,所有测试都通过了。尽管如此,当我运行整个测试类时,其中一些失败了。你能帮我找出这种行为的原因吗?这是我的课程和我的测试:
package com.topcoder.div2.stage1;
import java.util.Arrays;
public class GameOfStones {
private int iterations = 0;
public int count(int[] stones){
int result = checkEquality(stones);
return result;
}
private int checkEquality(int[] stones){
int count = 0;
int sum = 0;
for(int k = 0; k< stones.length;k++){
sum += stones[k];
}
if(stones.length > 0) {
for (int i = 0; i < sum; i++) {
Arrays.sort(stones);
if(stones[stones.length-1] != 3) {
int j = 0;
while (j < stones.length - 1) {
if (stones[j] == stones[j + 1]) {
count++;
}
j++;
}
if (count == stones.length - 1) {
return iterations;
}
stones[0] = stones[0] + 2;
stones[stones.length - 1] = stones[stones.length - 1] - 2;
iterations++;
count = 0;
}
}
}
return -1;
}
}
Test:
测试:
package com.topcoder.div2.stage1;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
public class GameOfStonesTest {
private GameOfStones gameOfStones = new GameOfStones();
@Test
public void test1() {
int expected = 0;
int[] given = {17};
int actual = gameOfStones.count(given);
assertEquals(expected, actual);
}
@Test
public void test2() {
int expected = 3;
int[] given ={7, 15, 9, 5};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test3() {
int expected = -1;
int[] given ={2, 8, 4};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test4() {
int expected = -1;
int[] given ={10, 15, 20, 12, 1, 20};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test5(){
int expected = 277;
int[] given ={17, 1, 27, 29, 13, 1, 27, 3, 19, 3, 25, 1, 11, 9, 7, 17, 31, 25, 5, 11, 31, 9,
15, 3, 3, 3, 11, 11, 1, 41, 5, 95, 7, 3, 41, 31, 7, 13, 15, 5, 17, 3, 9, 3, 11,
27, 1, 23, 15, 5, 43, 11, 17, 7, 1, 3, 13, 69, 3, 43, 21, 1, 25, 1, 3, 11, 5, 43,
13, 7, 15, 1, 1, 55, 37, 9, 5, 7, 21, 3, 23, 15, 1, 9, 3, 35, 13, 17, 7, 17, 27, 5,
9, 19, 13, 1, 1, 1, 29};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test6(){
int expected = 539;
int[] given ={1, 29, 11, 35, 57, 15, 85, 19, 5, 47, 53, 5, 63, 19, 13, 63, 27, 43, 53, 75, 67, 93, 33, 31, 47, 3,
63, 17, 11, 53, 35, 23, 17, 45, 31, 19, 63, 75, 5, 3, 49, 19, 11, 89, 21, 69,
71, 5, 45, 81, 31, 13, 11, 19, 7, 99, 33, 63, 19, 57, 73, 29, 35, 9, 47,
1, 17, 7, 13, 31, 5, 85, 95, 23, 45, 65, 63, 41, 81, 33, 45, 1, 15,
45, 19, 87, 51, 7, 13, 39, 1, 59, 29, 35, 1, 43};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test7() {
int expected = 0;
int[] given ={100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test8() {
int expected = 11;
int[] given ={3, 5, 21, 31};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
@Test
public void test9() {
int expected = 13;
int[] given ={44, 6, 46};
int actual = gameOfStones.count(given);
assertEquals(actual, expected);
}
}
P.S if you know any suggestions of improving the solution you are more than welcome to include them in your answer.
PS,如果您知道任何改进解决方案的建议,我们非常欢迎您将它们包含在您的答案中。
采纳答案by BarrySW19
You are sharing a single instance of the class under test across all tests. I'd remove the initial assignment and add this:
您在所有测试中共享被测类的单个实例。我会删除初始分配并添加以下内容:
private GameOfStones gameOfStones; // Don't create an instance here
@BeforeMethod
public void setUp() {
gameOfStones = new GameOfStones();
}
... which will use a new instance for each test. Good practice would also be to clean up after each test:
...这将为每个测试使用一个新实例。好的做法是在每次测试后进行清理:
@AfterMethod
public void tearDown() {
gameOfStones = null;
}
In the example given here, fixing the class scoped variable causing the problem to be method scoped instead would also fix the issue, but as the software under test gets more complex it's good to start doing proper test set up and tear down.
在此处给出的示例中,修复导致问题成为方法范围的类范围变量也可以解决问题,但是随着被测软件变得越来越复杂,最好开始进行适当的测试设置和拆除。
回答by CoderTest
You can also try @BeforeEach for Junit5
您也可以为 Junit5 尝试 @BeforeEach
@BeforeEach
public void setup() {
// Some code here
}
回答by sujata swamy
Since I am opening the same activity under test in many test cases executed one after another and same IntentsTestRule class activity
由于我在一个接一个执行的许多测试用例中打开相同的测试活动,并且相同的 IntentsTestRule 类活动
I could resolve the issue in my case by calling finishActivity on activityTestRule class and intentTestRule class
我可以通过在activityTestRule 类和intentTestRule 类上调用finishActivity 来解决我的问题
eg:
例如:
@After
fun method() {
mainActivityTestRule.finishActivity()
mIntentsRule.finishActivity()
}
回答by user07
I had same issue. I needed to mock a logger, which was a static field. So eventually class loader creates only a single instance of the static field during the first invocation of a class under the test and disregards all further mocking and stubbing. When run separately, test was green, because the logger was initialized and loaded as expected, but when run all together, with other test methods, it got initialized as a concrete object, not a mock. Workaround:
我有同样的问题。我需要模拟一个记录器,它是一个静态字段。因此,最终类加载器在测试下的类的第一次调用期间仅创建静态字段的单个实例,而忽略所有进一步的模拟和存根。单独运行时,test 是绿色的,因为记录器已按预期初始化和加载,但是当一起运行时,与其他测试方法一起运行时,它被初始化为具体对象,而不是模拟。解决方法:
- create
@BeforeClass
method to ensure that the right instance of static field will be created in the first place:
- create
@BeforeClass
方法以确保首先创建正确的静态字段实例:
@BeforeClass
public static void setupBeforeClass() {
PowerMockito.mockStatic(LoggerFactory.class);
loggerMock = mock(Logger.class);
when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMock);
}
- Interactions on the mock are getting accumulated from different test executions. Therefore, to be sure that you get a clean instance of the mock on each test method execution, reset the mock whether in
@Before
or@After
method:
- 模拟上的交互是从不同的测试执行中积累起来的。因此,要确保在每个测试方法执行时获得一个干净的模拟实例,请重置模拟,无论是 in
@Before
还是@After
method:
@Before
public void setup() {
// Reset interactions on the mocked logger
Mockito.reset(loggerMock);
}
Note, that in my example I used PowerMock so you need a corresponding runner @RunWith(PowerMockRunner.class)
and @PrepareForTest({LoggerFactory.class, MyClass.class)}
statements.
请注意,在我的示例中,我使用了 PowerMock,因此您需要相应的运行程序@RunWith(PowerMockRunner.class)
和@PrepareForTest({LoggerFactory.class, MyClass.class)}
语句。
回答by Udara Seneviratne
I would like to add my experience regarding this issue.
我想补充一下我在这个问题上的经验。
After doing many debuggins I could confirm that there is no garbage data in the DB and also no static variables effects to the functionality.
经过多次调试后,我可以确认数据库中没有垃圾数据,也没有静态变量对功能产生影响。
And also the same unit tests, pass individually and all at once as expected in another environment.
还有相同的单元测试,在另一个环境中按预期单独和一次性通过。
Java versions, MySQL versions are the same in both environments. The only difference was the maven version. So, I configured the same maven version which was used in the successful environment.
Java 版本、MySQL 版本在两种环境中都是相同的。唯一的区别是 Maven 版本。所以,我配置了与成功环境中使用的相同的maven版本。
Then after issue solved.
然后问题解决后。