@mSolo
2015-04-15T14:46:03.000000Z
字数 10470
阅读 2087
Android 测试 TDD 持续集成
The RenamingMockContext class
public class RenamingMockContext extends RenamingDelegatingContext {private static final String PREFIX = "test.";public RenamingMockContext(Context context) {super(context, PREFIX);}@Overridepublic SharedPreferences getSharedPreferences(String name, int mode) {return super.getSharedPreferences(PREFIX + name, mode);} // Now, we have full control over how preferences, databases, and files are stored.}
public class TemperatureConverterApplicationTests extendsApplicationTestCase<TemperatureConverterApplication> {public TemperatureConverterApplicationTests() {this("TemperatureConverterApplicationTests");}public TemperatureConverterApplicationTests(String name) {super(TemperatureConverterApplication.class);setName(name);}public void testSetAndRetreiveDecimalPlaces() {RenamingMockContext mockContext = new RenamingMockContext(getContext());setContext(mockContext);createApplication();TemperatureConverterApplication application = getApplication();application.setDecimalPlaces(3);assertEquals(3, application.getDecimalPlaces());}}
public class TemperatureConverterApplication extends Application {private static final int DECIMAL_PLACES_DEFAULT = 2;private static final String KEY_DECIMAL_PLACES = ".KEY_DECIMAL_PLACES";private SharedPreferences sharedPreferences;@Overridepublic void onCreate() {super.onCreate();sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);}public void setDecimalPlaces(int places) {Editor editor = sharedPreferences.edit();editor.putInt(KEY_DECIMAL_PLACES, places);editor.apply();}public int getDecimalPlaces() {return sharedPreferences.getInt(KEY_DECIMAL_PLACES, DECIMAL_PLACES_DEFAULT);}}
public class ForwardingActivity extends Activity {private static final int GHOSTBUSTERS = 999121212;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_forwarding);View button = findViewById(R.id.forwarding_go_button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("tel:" + GHOSTBUSTERS);startActivity(intent);finish();}});}}
public class ForwardingActivityTest extendsActivityUnitTestCase<ForwardingActivity> {private Intent startIntent;public ForwardingActivityTest() {super(ForwardingActivity.class);}@Overrideprotected void setUp() throws Exception {super.setUp();Context context = getInstrumentation().getContext();startIntent = new Intent(context, ForwardingActivity.class);}public void testLaunchingSubActivityFiresIntentAndFinishesSelf() {Activity activity = startActivity(startIntent, null, null);View button = activity.findViewById(R.id.forwarding_go_button);button.performClick();assertNotNull(getStartedActivityIntent());assertTrue(isFinishCalled());}public void testExampleOfLifeCycleCreation() {Activity activity = startActivity(startIntent, null, null);getInstrumentation().callActivityOnStart(activity);getInstrumentation().callActivityOnResume(activity);// 进行测试getInstrumentation().callActivityOnPause(activity);// 进行测试getInstrumentation().callActivityOnStop(activity);// At this point, you could confirm that the activity has shut itself down appropriately,// or you could use a Mock Context to confirm that your activity has released any// system resources it should no longer be holding.// ActivityUnitTestCase.tearDown() is always automatically called// and will take care of calling onDestroy().}}
textView = (TextView) findViewById(R.id.mock_text_view);try {FileInputStream fis = openFileInput(FILE_NAME);textView.setText(convertStreamToString(fis));} catch (FileNotFoundException e) {textView.setText("File not found");}
$ adb shell$ echo "This is real data" > data/data/com.blundell.tut/files/my_file.txt$ echo "This is *MOCK* data" > /data/data/com.blundell.tut/files/test.my_file.txt
public class MockContextExampleTestextends ActivityUnitTestCase<MockContextExampleActivity> {private static final String PREFIX = "test.";private RenamingDelegatingContext mockContext;public MockContextExampleTest() {super(MockContextExampleActivity.class);}@Overrideprotected void setUp() throws Exception {super.setUp();mockContext = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), PREFIX);mockContext.makeExistingFilesAndDbsAccessible();}public void testSampleTextDisplayed() {setActivityContext(mockContext); // must called before startActivity()startActivity(new Intent(), null, null);assertEquals("This is *MOCK* data\n", getActivity().getText());}}
public void testExceptionForLessThanAbsoluteZeroC() {try {TemperatureConverter.celsiusToFahrenheit(ABSOLUTE_ZERO_C - 1);fail();} catch (InvalidTemperatureException ex) {// do nothing we expect this exception!}}
public class DummyServiceTest extends ServiceTestCase<DummyService> {public DummyServiceTest() {super(DummyService.class);}public void testBasicStartup() {Intent startIntent = new Intent();startIntent.setClass(getContext(), DummyService.class);startService(startIntent);}public void testBindable() {Intent startIntent = new Intent();startIntent.setClass(getContext(), DummyService.class);bindService(startIntent);}}
dependencies {androidTestCompile('com.google.dexmaker:dexmaker-mockito:1.1')}packagingOptions {exclude 'META-INF/LICENSE'exclude 'folder/duplicatedFileName'}
public void testTextChangedFilterWorksForCharacterInput() {assertEditNumberTextChangeFilter("A1A", "1");}/*** @param input the text to be filtered* @param output the result you expect once the input has been filtered*/private void assertEditNumberTextChangeFilter(String input, String output) {int lengthAfter = output.length();TextWatcher mockTextWatcher = mock(TextWatcher.class);editNumber.addTextChangedListener(mockTextWatcher);editNumber.setText(input);verify(mockTextWatcher).afterTextChanged(editableCharSequenceEq(output));verify(mockTextWatcher).onTextChanged(charSequenceEq(output), eq(0), eq(0), eq(lengthAfter));verify(mockTextWatcher).beforeTextChanged(charSequenceEq(""), eq(0), eq(0), eq(lengthAfter));}
class CharSequenceMatcher extends ArgumentMatcher<CharSequence> {private final CharSequence expected;static CharSequence charSequenceEq(CharSequence expected) {return argThat(new CharSequenceMatcher(expected));}CharSequenceMatcher(CharSequence expected) {this.expected = expected;}@Overridepublic boolean matches(Object actual) {return expected.toString().equals(actual.toString());}@Overridepublic void describeTo(Description description) {description.appendText(expected.toString());}}
public class FocusTest extends AndroidTestCase {private FocusFinder focusFinder;private ViewGroup layout;private Button leftButton;private Button centerButton;private Button rightButton;@Overrideprotected void setUp() throws Exception {super.setUp();focusFinder = FocusFinder.getInstance();Context context = getContext(); // inflate the layoutLayoutInflater inflater = LayoutInflater.from(context);layout = (ViewGroup) inflater.inflate(R.layout.view_focus, null);// manually measure it, and lay it outlayout.measure(500, 500);layout.layout(0, 0, 500, 500);leftButton = (Button) layout.findViewById(R.id.focus_left_button);centerButton = (Button) layout.findViewById(R.id.focus_center_button);rightButton = (Button) layout.findViewById(R.id.focus_right_button);}public void testGoingRightFromLeftButtonJumpsOverCenterToRight() {View actualNextButton = focusFinder.findNextFocus(layout, leftButton, View.FOCUS_RIGHT);String msg = "right should be next focus from left";assertEquals(msg, this.rightButton, actualNextButton);}public void testGoingLeftFromRightButtonGoesToCenter() {View actualNextButton = focusFinder.findNextFocus(layout, rightButton, View.FOCUS_LEFT);String msg = "center should be next focus from right";assertEquals(msg, this.centerButton, actualNextButton);}}
public class ParserExampleActivityTest extends AndroidTestCase {public void testParseXml() throws IOException {InputStream assetsXml = getContext().getAssets().open("my_document.xml");String result = parseXml(assetsXml);assertNotNull(result);}}
public void assertNotInLowMemoryCondition() {//Verification: check if it is in low memoryActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();((ActivityManager)getActivity().getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(mi);assertFalse("Low memory condition", mi.lowMemory);}private String captureProcessInfo() {InputStream in = null;try {String cmd = "ps";Process p = Runtime.getRuntime().exec(cmd);in = p.getInputStream();Scanner scanner = new Scanner(in);scanner.useDelimiter("\\A");return scanner.hasNext() ? scanner.next() : "scanner error";} catch (IOException e) {fail(e.getLocalizedMessage());} finally {if (in != null) {try {in.close();} catch (IOException ignore) {}}}return "captureProcessInfo error";}// Log.d(TAG, captureProcessInfo());
D/ActivityTest(1): USER PID PPID VSIZE RSS WCHAN PC State NAMED/ActivityTest(1): root 1 0 312[KB] 220 c009b74c 0000ca4c S /initD/ActivityTest(1): root 2 0 0 0 c004e72c 00000000 S kthreaddD/ActivityTest(1): root 3 2 0 0 c003fdc8 00000000 S ksoftirqd/0D/ActivityTest(1): root 4 2 0 0 c004b2c4 00000000 S events/0D/ActivityTest(1): root 5 2 0 0 c004b2c4 00000000 S khelperD/ActivityTest(1): root 6 2 0 0 c004b2c4 00000000 S suspendD/ActivityTest(1): root 7 2 0 0 c004b2c4 00000000 S kblockd/0D/ActivityTest(1): root 8 2 0 0 c004b2c4 00000000 S cqueueD/ActivityTest(1): root 9 2 0 0 c018179c 00000000 S kseriod
dependencies {// other dependenciesandroidTestCompile('com.android.support.test.espresso:espresso-core:2.0')}android {defaultConfig {// other configurationtestInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"}// Annoyingly there is a overlap with Espresso dependencies at the moment// add this closure to fix internal jar file name clashespackagingOptions {exclude 'LICENSE.txt'}}
public class ExampleEspressoTest extendsActivityInstrumentationTestCase2<EspressoActivity> {public ExampleEspressoTest() {super(EspressoActivity.class);}@Overridepublic void setUp() throws Exception {getActivity();}public void testClickingButtonShowsImage() {Espresso.onView(ViewMatchers.withId(R.id.espresso_button_order)).perform(ViewActions.click());Espresso.onView(ViewMatchers.withId(R.id.espresso_imageview_cup)) .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));}public void testClickingButtonShowsImage() {Espresso.onView(withId(R.id.espresso_button_order)).perform(click());Espresso.onView(withId(R.id.espresso_imageview_cup)).check(matches(isDisplayed()));}}