[关闭]
@mSolo 2015-04-13T23:30:36.000000Z 字数 7867 阅读 1685

Stockeye 持续集成之路 —— NotificationStockQuote 开发实录

Jekins Android CI 持续集成 TDD


预构

项目概览

项目 build.gradle

  1. buildscript {
  2. repositories {
  3. jcenter()
  4. }
  5. dependencies {
  6. classpath 'com.android.tools.build:gradle:0.13.2'
  7. classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+'
  8. }
  9. }
  10. allprojects {
  11. repositories {
  12. jcenter()
  13. }
  14. }

App build.gradle

  1. apply plugin: 'com.android.application'
  2. android {
  3. compileSdkVersion 18
  4. buildToolsVersion '19.1.0'
  5. defaultConfig {
  6. applicationId "com.msolo.stockeye"
  7. minSdkVersion 16
  8. targetSdkVersion 18
  9. versionCode 1
  10. versionName "1.0"
  11. }
  12. buildTypes {
  13. release {
  14. runProguard false
  15. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  16. }
  17. }
  18. packagingOptions {
  19. exclude 'META-INF/NOTICE'
  20. exclude 'META-INF/LICENSE'
  21. exclude 'META-INF/LICENSE.txt'
  22. exclude 'LICENSE.txt'
  23. }
  24. }
  25. dependencies {
  26. compile fileTree(dir: 'libs', include: ['*.jar'])
  27. compile 'com.android.support:support-v4:19+'
  28. androidTestCompile 'org.hamcrest:hamcrest-integration:1.1'
  29. androidTestCompile 'org.hamcrest:hamcrest-core:1.1'
  30. androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
  31. androidTestCompile('junit:junit:4.+') {
  32. exclude module: 'hamcrest-core'
  33. }
  34. androidTestCompile('org.robolectric:robolectric:2.3') {
  35. exclude module: 'classworlds'
  36. exclude module: 'commons-logging'
  37. exclude module: 'httpclient'
  38. exclude module: 'maven-artifact'
  39. exclude module: 'maven-artifact-manager'
  40. exclude module: 'maven-error-diagnostics'
  41. exclude module: 'maven-model'
  42. exclude module: 'maven-project'
  43. exclude module: 'maven-settings'
  44. exclude module: 'plexus-container-default'
  45. exclude module: 'plexus-interpolation'
  46. exclude module: 'plexus-utils'
  47. exclude module: 'support-v4'
  48. exclude module: 'wagon-file'
  49. exclude module: 'wagon-http-lightweight'
  50. exclude module: 'wagon-provider-api'
  51. }
  52. }
  53. apply plugin: 'robolectric'

目录结构

  1. | build.gradle
  2. | src
  3. | |- androidTest
  4. | |- java/com/msolo/stockeye/MainActivityTest.java
  5. | |- java/com/msolo/stockeye/StockeyeApplication.java
  6. | |- main
  7. | |- java/com/msolo/stockeye/MainActivity.java
  8. | |- java/com/msolo/stockeye/StockeyeApplication.java

TDD 示范程序

  1. @RunWith(RobolectricTestRunner.class)
  2. public class MainActivityTest {
  3. @Test
  4. public void testActivityDisplayHelloWorldSuccessful() {
  5. String hello = new MainActivity().getResources().getString(R.string.hello_world);
  6. assertEquals("Hello World!", hello);
  7. }
  8. }

更多例子

  1. public void testListScrolling() {
  2. listView.scrollTo(0, 0);
  3. TouchUtils.dragQuarterScreenUp(this, activity);
  4. int actualItemPosition = listView.getFirstVisiblePosition();
  5. assertTrue("Wrong position", actualItemPosition > 0);
  6. }

示范测试

E:\android_workspaces\TDDStockeye>d:gradle-2.1\bin\gradle test
:app:preBuild
:app:preDebugBuild
:app:checkDebugManifest
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJava UP-TO-DATE
:app:compileTestDebugJava
:app:processTestDebugResources UP-TO-DATE
:app:testDebugClasses
:app:testDebug
:app:test
BUILD SUCCESSFUL
Total time: 11.647 secs

测试结果:file:///E:/android_workspaces/TDDStockeye/app/build/test-report/debug/index.html

NotificationStockQuote TDD

第01次(A001):测试默认构造器为私有

注:TDD 快速测试(仅示范,真实项目中不必如此繁琐)

  1. // NotificationStockQuoteTest.java
  2. @Test
  3. public void testSingletonOfNotificationStockQuote() {
  4. notificationStockQuote = new NotificationStockQuote();
  5. NotificationStockQuote notificationStockQuoteAnother = new NotificationStockQuote();
  6. assertNotSame(notificationStockQuoteAnother, notificationStockQuote);
  7. }
  8. // NotificationStockQuote.java
  9. public class NotificationStockQuote {
  10. private static NotificationStockQuote sInstance = null;
  11. private NotificationStockQuote() {}
  12. public static NotificationStockQuote getInstance() {
  13. return new NotificationStockQuote();
  14. }
  15. }

第02次(A002):测试默认构造器为私有,并且构造生成的对象为单例对象

  1. // NotificationStockQuoteTest.java
  2. @Test
  3. public void testSingletonOfNotificationStockQuote() {
  4. NotificationStockQuote notificationStockQuoteAnother = NotificationStockQuote.getInstance();
  5. notificationStockQuote = NotificationStockQuote.getInstance();
  6. assertSame(notificationStockQuoteAnother, notificationStockQuote);
  7. }
  8. // NotificationStockQuote.java
  9. public class NotificationStockQuote {
  10. private static NotificationStockQuote sInstance = null;
  11. private NotificationStockQuote() {}
  12. public static NotificationStockQuote getInstance() {
  13. return new NotificationStockQuote();
  14. }
  15. }

第03次(A003):测试默认构造器为私有,并且构造生成的对象为单例对象

  1. // NotificationStockQuoteTest.java
  2. @Before
  3. public void setUp() {
  4. notificationStockQuote = NotificationStockQuote.getInstance();
  5. }
  6. @Test
  7. public void testSingletonOfNotificationStockQuote() {
  8. NotificationStockQuote notificationStockQuoteAnother = NotificationStockQuote.getInstance();
  9. assertSame(notificationStockQuoteAnother, notificationStockQuote);
  10. }
  11. // NotificationStockQuote.java
  12. public class NotificationStockQuote {
  13. private static NotificationStockQuote sInstance = null;
  14. private NotificationStockQuote() {}
  15. public static NotificationStockQuote getInstance() {
  16. if (null == sInstance) {
  17. sInstance = new NotificationStockQuote();
  18. }
  19. return sInstance;
  20. }
  21. }

第04次(B001):测试 NotificationStockQuote 完成对 Notification 服务管理对象的初始化

  1. // NotificationStockQuoteTest.java
  2. @Test
  3. public void testInit() {
  4. NotificationManager notificationManager = (NotificationManager) Robolectric.application.getSystemService(Context.NOTIFICATION_SERVICE);
  5. notificationStockQuote.init();
  6. NotificationStockQuote.HelperTestNotificationStockQuote helper = notificationStockQuote.new HelperTestNotificationStockQuote();
  7. assertNotNull(helper.getNotificationManager());
  8. assertSame(notificationManager, helper.getNotificationManager());
  9. }
  10. // NotificationStockQuote.java
  11. public void init() {
  12. }
  13. /**
  14. *
  15. * This is an inner class for helping test NotificationStockQuote,
  16. * and it should be delete in production.
  17. *
  18. * Date | Name | Change
  19. *--------+--------------------------------------------------
  20. * 141119 | mSolo | REQ #001: add method getNotificationManager().
  21. *
  22. */
  23. public class HelperTestNotificationStockQuote {
  24. public HelperTestNotificationStockQuote() {}
  25. public NotificationManager getNotificationManager() {
  26. return notificationManager;
  27. }
  28. }


第05次(B002):测试 NotificationStockQuote 完成对 Notification 对象的初始化

  1. @Test
  2. public void testInit() {
  3. NotificationManager notificationManager = (NotificationManager) Robolectric.application.getSystemService(Context.NOTIFICATION_SERVICE);
  4. //notificationStockQuote.init();
  5. MimicNotificationStockQuote mimic = new MimicNotificationStockQuote();
  6. mimic.init();
  7. assertNotNull(mimic.notificationManager);
  8. assertSame(notificationManager, mimic.notificationManager);
  9. }
  10. /**
  11. *
  12. * This is an inner class for mimic NotificationStockQuote.
  13. *
  14. * Date | Name | Change
  15. *--------+--------------------------------------------------
  16. * 141119 | mSolo | REQ #001: mimic method init().
  17. *
  18. */
  19. private class MimicNotificationStockQuote {
  20. public NotificationManager notificationManager = null;
  21. public MimicNotificationStockQuote() {}
  22. public void init() {
  23. notificationManager = (NotificationManager)Robolectric.application.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
  24. }
  25. }
  26. // NotificationStockQuote.java
  27. public void init() {
  28. notificationManager = (NotificationManager) StockeyeApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
  29. }

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注