使用 ActivityInstrumentationTestCase2 测试预期异常
Testing Expected Exceptions with ActivityInstrumentationTestCase2
我想对这个简单的单元测试activity(请关注onClick()函数):
public class MainActivity extends Activity implements OnClickListener {
private EditText edtValue1;
private EditText edtValue2;
private TextView txtResult;
private Button btnAdd;
private Button btnMuliply;
private ICalculator calculator;
final String LOG_TAG = "MainScreen";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtValue1 = (EditText) findViewById(R.id.value1);
edtValue2 = (EditText) findViewById(R.id.value2);
txtResult = (TextView) findViewById(R.id.result);
btnAdd = (Button) findViewById(R.id.addValues);
btnMuliply = (Button) findViewById(R.id.multiplyValues);
btnAdd.setOnClickListener(this);
btnMuliply.setOnClickListener(this);
calculator = new Calculator();
}
@Override
public void onClick(View v) {
int val1 = 0;
int val2 = 0;
try {
val1 = Integer.parseInt(edtValue1.getText().toString());
val2 = Integer.parseInt(edtValue2.getText().toString());
}
catch (NumberFormatException exc) {
Log.e(LOG_TAG, exc.getMessage(), exc);
throw exc;
}
switch (v.getId()) {
case R.id.addValues:
txtResult.setText(calculator.addNumbers(val1, val2).toString());
break;
case R.id.multiplyValues:
txtResult.setText(calculator.multiplyNumbers(val1, val2).toString());
break;
}
}
}
外观是这样的:
这里是简单的JUnit测试用例(请关注testAddDecimalValues_NumberFormatException()方法):
public class MainActivityTest extends
ActivityInstrumentationTestCase2<MainActivity> {
MainActivity mainActivity;
private TextView txtResult;
public MainActivityTest() {
super(MainActivity.class);
}
@Before
public void setUp() throws Exception {
mainActivity = getActivity();
txtResult = (TextView) mainActivity.findViewById(R.id.result);
}
private final static String NUMBER_24 = "2 4 ENTER ";
private final static String NUMBER_74 = "7 4 ENTER ";
private final static String ADD_RESULT = "98";
@After
protected void tearDown() throws Exception {
}
@Test
public void testAddValues() {
sendKeys(NUMBER_24 + NUMBER_74 + "ENTER");
// get result
String mathResult = txtResult.getText().toString();
assertTrue("Add result should be 98", mathResult.equals(ADD_RESULT));
}
private final static String NUMBER_5_DOT_5 = "5 PERIOD 5 ENTER ";
@Test(expected = NumberFormatException.class)
public void testAddDecimalValues_NumberFormatException() {
sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");
}
}
当我启动单元测试时 testAddValues() 工作正常但 testAddDecimalValues_NumberFormatException() 方法没有考虑expected = IllegalArgumentException.class
和 testAddDecimalValues_NumberFormatException() 测试失败...
这是 Logcat :
[2015-05-27 12:52:42 - SimpleCalcTest] Launching instrumentation android.test.InstrumentationTestRunner on 0123456789ABCDEF
[2015-05-27 12:52:42 - SimpleCalcTest] Test run failed: Instrumentation run failed due to 'Process crashed.'
[2015-05-27 12:52:42 - SimpleCalcTest] Test run finished
[2015-05-27 12:52:43 - SimpleCalcTest] Sending test information to Eclipse
[2015-05-27 12:52:44 - SimpleCalcTest] Test run failed: Instrumentation run failed due to 'java.lang.NumberFormatException'
[2015-05-27 12:52:44 - SimpleCalcTest] Test run finished
问题是:你知道我如何使用 ActivityInstrumentationTestCase2 功能测试预期异常吗?
非常感谢。
PS :我尝试了与 http://www.javacodegeeks.com/2013/02/testing-expected-exceptions-with-junit-rules.html 不同的方法,但我得到了相同的结果
ActivityInstrumentationTestCase2
扩展了 junit.framework.TestCase
,因此您不能在 org.junit
树中使用注释或 类(如 @Test
和 ExpectedException
) 使用 ActivityInstrumentationTestCase2
的测试
相反,这样做:
public void testAddDecimalValues_NumberFormatException() {
try {
sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");
fail("NumberFormatException not thrown");
} catch (NumberFormatException expected) {
}
}
编辑: 第二个问题是您的非测试代码。当你捕获异常时,你只有三个选择:
- 捕获异常,记录异常,并在不抛出的情况下继续
- 捕获异常,用另一个异常包装异常,并抛出新的异常(不记录)。
- 重试 1-n 次,如果仍然失败,则执行选项 1 或 2(仅供专家使用;此选项可能对远程调用有意义,并且您需要了解成本在循环中抛出异常)
注意选项 2,异常将由调用代码处理或由调用代码记录,因此如果您计划抛出异常,则无需记录异常。
所以替换这个:
try {
val1 = Integer.parseInt(edtValue1.getText().toString());
val2 = Integer.parseInt(edtValue2.getText().toString());
} catch (NumberFormatException exc) {
Log.e(LOG_TAG, exc.getMessage(), exc);
throw exc;
}
有了这个:
val1 = Integer.parseInt(edtValue1.getText().toString());
val2 = Integer.parseInt(edtValue2.getText().toString());
最后,我认为 ActivityInstrumentationTestCase2 无法测试预期的异常,因为 ActivityInstrumentationTestCase2 用于自动化手动测试和手动测试不能遇到异常......
这就是为什么为了测试错误情况,我们必须只对业务进行单元测试 class.
在MainActivityclass中,我要处理异常。如果你愿意,我可以 post 我的代码解决方案。
谢谢
我想对这个简单的单元测试activity(请关注onClick()函数):
public class MainActivity extends Activity implements OnClickListener {
private EditText edtValue1;
private EditText edtValue2;
private TextView txtResult;
private Button btnAdd;
private Button btnMuliply;
private ICalculator calculator;
final String LOG_TAG = "MainScreen";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtValue1 = (EditText) findViewById(R.id.value1);
edtValue2 = (EditText) findViewById(R.id.value2);
txtResult = (TextView) findViewById(R.id.result);
btnAdd = (Button) findViewById(R.id.addValues);
btnMuliply = (Button) findViewById(R.id.multiplyValues);
btnAdd.setOnClickListener(this);
btnMuliply.setOnClickListener(this);
calculator = new Calculator();
}
@Override
public void onClick(View v) {
int val1 = 0;
int val2 = 0;
try {
val1 = Integer.parseInt(edtValue1.getText().toString());
val2 = Integer.parseInt(edtValue2.getText().toString());
}
catch (NumberFormatException exc) {
Log.e(LOG_TAG, exc.getMessage(), exc);
throw exc;
}
switch (v.getId()) {
case R.id.addValues:
txtResult.setText(calculator.addNumbers(val1, val2).toString());
break;
case R.id.multiplyValues:
txtResult.setText(calculator.multiplyNumbers(val1, val2).toString());
break;
}
}
}
外观是这样的:
这里是简单的JUnit测试用例(请关注testAddDecimalValues_NumberFormatException()方法):
public class MainActivityTest extends
ActivityInstrumentationTestCase2<MainActivity> {
MainActivity mainActivity;
private TextView txtResult;
public MainActivityTest() {
super(MainActivity.class);
}
@Before
public void setUp() throws Exception {
mainActivity = getActivity();
txtResult = (TextView) mainActivity.findViewById(R.id.result);
}
private final static String NUMBER_24 = "2 4 ENTER ";
private final static String NUMBER_74 = "7 4 ENTER ";
private final static String ADD_RESULT = "98";
@After
protected void tearDown() throws Exception {
}
@Test
public void testAddValues() {
sendKeys(NUMBER_24 + NUMBER_74 + "ENTER");
// get result
String mathResult = txtResult.getText().toString();
assertTrue("Add result should be 98", mathResult.equals(ADD_RESULT));
}
private final static String NUMBER_5_DOT_5 = "5 PERIOD 5 ENTER ";
@Test(expected = NumberFormatException.class)
public void testAddDecimalValues_NumberFormatException() {
sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");
}
}
当我启动单元测试时 testAddValues() 工作正常但 testAddDecimalValues_NumberFormatException() 方法没有考虑expected = IllegalArgumentException.class
和 testAddDecimalValues_NumberFormatException() 测试失败...
这是 Logcat :
[2015-05-27 12:52:42 - SimpleCalcTest] Launching instrumentation android.test.InstrumentationTestRunner on 0123456789ABCDEF
[2015-05-27 12:52:42 - SimpleCalcTest] Test run failed: Instrumentation run failed due to 'Process crashed.'
[2015-05-27 12:52:42 - SimpleCalcTest] Test run finished
[2015-05-27 12:52:43 - SimpleCalcTest] Sending test information to Eclipse
[2015-05-27 12:52:44 - SimpleCalcTest] Test run failed: Instrumentation run failed due to 'java.lang.NumberFormatException'
[2015-05-27 12:52:44 - SimpleCalcTest] Test run finished
问题是:你知道我如何使用 ActivityInstrumentationTestCase2 功能测试预期异常吗?
非常感谢。
PS :我尝试了与 http://www.javacodegeeks.com/2013/02/testing-expected-exceptions-with-junit-rules.html 不同的方法,但我得到了相同的结果
ActivityInstrumentationTestCase2
扩展了 junit.framework.TestCase
,因此您不能在 org.junit
树中使用注释或 类(如 @Test
和 ExpectedException
) 使用 ActivityInstrumentationTestCase2
相反,这样做:
public void testAddDecimalValues_NumberFormatException() {
try {
sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + "ENTER");
fail("NumberFormatException not thrown");
} catch (NumberFormatException expected) {
}
}
编辑: 第二个问题是您的非测试代码。当你捕获异常时,你只有三个选择:
- 捕获异常,记录异常,并在不抛出的情况下继续
- 捕获异常,用另一个异常包装异常,并抛出新的异常(不记录)。
- 重试 1-n 次,如果仍然失败,则执行选项 1 或 2(仅供专家使用;此选项可能对远程调用有意义,并且您需要了解成本在循环中抛出异常)
注意选项 2,异常将由调用代码处理或由调用代码记录,因此如果您计划抛出异常,则无需记录异常。
所以替换这个:
try {
val1 = Integer.parseInt(edtValue1.getText().toString());
val2 = Integer.parseInt(edtValue2.getText().toString());
} catch (NumberFormatException exc) {
Log.e(LOG_TAG, exc.getMessage(), exc);
throw exc;
}
有了这个:
val1 = Integer.parseInt(edtValue1.getText().toString());
val2 = Integer.parseInt(edtValue2.getText().toString());
最后,我认为 ActivityInstrumentationTestCase2 无法测试预期的异常,因为 ActivityInstrumentationTestCase2 用于自动化手动测试和手动测试不能遇到异常...... 这就是为什么为了测试错误情况,我们必须只对业务进行单元测试 class.
在MainActivityclass中,我要处理异常。如果你愿意,我可以 post 我的代码解决方案。
谢谢