2015-03-17 16 views
9

Tôi đang cố chạy thử nghiệm đơn vị bằng cách sử dụng Robolectric; chúng chạy tốt trong Android Studio, nhưng các thử nghiệm tương tự không thành công khi chạy trong dòng lệnh - đó là một vấn đề lớn, tôi cần để có thể chạy chúng từ nền tảng tích hợp liên tục của tôi, không chỉ từ một IDE.Kiểm tra Robolectric chạy trong Android Studio nhưng không phải trên dòng lệnh

Tôi nghi ngờ rằng tôi thiếu một số đối số dòng lệnh (nói, một classpath hoặc một cái gì đó tương tự) hoặc gọi nhiệm vụ sai - nếu không thử nghiệm sẽ không chạy ở tất cả từ Android Studio. Một số chi tiết liên quan; kiểm tra như sau:

@RunWith(RobolectricTestRunner.class) 
@Config(manifest = "app/src/main/AndroidManifest.xml", resourceDir = "res", emulateSdk = 19) 
public class SplashActivityTest { 

    @Test 
    public void testActivity() { 
     SplashActivity splashActivity = new SplashActivity(); 
     String appName = splashActivity.getString(R.string.app_name); // HERE, line 20 
     assertEquals(appName, "App"); 
    } 

} 

Như đã đề cập ở trên, nó chạy tốt trong Android Studio (bằng cách kích chuột phải vào file test và chọn Run 'SplashActivityTest') nhưng khi chạy nó từ dòng lệnh nó không thành công trong dòng được đánh dấu bằng HERE, với stack trace sau:

android.content.res.Resources$NotFoundException: unknown resource 2131492893 
    at org.robolectric.shadows.ShadowAssetManager.getAndResolve(ShadowAssetManager.java:309) 
    at org.robolectric.shadows.ShadowAssetManager.getResourceText(ShadowAssetManager.java:69) 
    at android.content.res.AssetManager.getResourceText(AssetManager.java) 
    at android.content.res.Resources.getText(Resources.java:240) 
    at org.robolectric.shadows.ShadowResources.getText(ShadowResources.java:361) 
    at android.content.res.Resources.getText(Resources.java) 
    at android.content.res.Resources.getString(Resources.java:330) 
    at org.robolectric.shadows.ShadowContext.getString(ShadowContext.java:39) 
    at org.robolectric.shadows.ShadowContextWrapper.getString(ShadowContextWrapper.java:69) 
    at android.content.Context.getString(Context.java) 
    at path.to.myApp.activities.SplashActivityTest.testActivity(SplashActivityTest.java:20) 
    // ... and so on ... 

tôi đang sử dụng này để chạy từ dòng lệnh (chú ý rằng ở đây và trong Android Studio tôi đang sử dụng wrapper Gradle):

project-root$ ./gradlew test --continue 

Ngoài ra: Tôi đang sử dụng Android Studio 1.1.0, Gradle phiên bản là 2.3, phiên bản Robolectric là 3.0-SNAPSHOT và phiên bản plugin Gradle Robolectric là 1.0.1

+0

Oscar, bạn có thể chạy nó với tùy chọn '--debug'. Tôi hy vọng rằng bạn sẽ thấy thông báo về sự cố để tìm tệp kê khai và sử dụng tệp mặc định –

+0

@EugenMartynov Bạn đang đi đúng hướng, tôi nhận được thông báo này trên bảng điều khiển: 'CẢNH BÁO: Không tìm thấy tệp kê khai nào tại ./app/src/ tệp chính/AndroidManifest.xml. Chỉ rơi vào tài nguyên hệ điều hành Android.' bạn có thể xây dựng? –

Trả lời

8

Nó chỉ ra rằng đây là một vấn đề được biết đến. Tài nguyên của dự án được tìm kiếm trong thư mục sai khi chạy thử nghiệm từ dòng lệnh, dưới đây là link cho vấn đề; bây giờ các workaround là để viết một Á hậu kiểm tra tùy chỉnh như chứng minh here:

public class RobolectricGradleTestRunner extends RobolectricTestRunner { 

    public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError { 
     super(testClass); 
     String buildVariant = (BuildConfig.FLAVOR.isEmpty() ? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE; 
     String intermediatesPath = BuildConfig.class.getResource("").toString().replace("file:", ""); 
     intermediatesPath = intermediatesPath.substring(0, intermediatesPath.indexOf("/classes")); 

     System.setProperty("android.package", BuildConfig.APPLICATION_ID); 
     System.setProperty("android.manifest", intermediatesPath + "/manifests/full/" + buildVariant + "/AndroidManifest.xml"); 
     System.setProperty("android.resources", intermediatesPath + "/res/" + buildVariant); 
     System.setProperty("android.assets", intermediatesPath + "/assets/" + buildVariant); 
    } 

} 

Các trường hợp kiểm tra phải được cập nhật phù hợp để sử dụng bài thi Á hậu tùy chỉnh thay vì các @Config chú thích:

@RunWith(RobolectricGradleTestRunner.class) 
public class SplashActivityTest { 
    // tests same as before 
} 

Ngoài ra, chúng tôi khuyên bạn nên thực hiện một clean khi chạy thử nghiệm từ dòng lệnh, do cách giải quyết phụ thuộc vào nội dung của thư mục xây dựng, chúng tôi không muốn có dữ liệu cũ ở đó:

project-root$ ./gradlew clean test --continue 
+0

Giống như phụ lục cho câu trả lời này.Kể từ ngày 24/3/2015, tôi khuyên bạn nên sử dụng thư viện gần đây nhất ** Robolectric 3.0-SNAPSHOT **. Ảnh chụp nhanh này đã được tích hợp sẵn trong ** RobolectricGradleTestRunner ** cũng sẽ hoạt động với các phần tử BuildVariant (Flavour, Type, v.v.). Với điều này, bạn không cần phải tự mình viết một bản thử nghiệm. Đối với nhân vật được cập nhật [một lớp cấu hình không đổi có thể được định nghĩa như thế này] (https://github.com/robolectric/robolectric/blame/master/robolectric/src/test/java/org/robolectric/RobolectricGradleTestRunnerTest.java#L67) . – abest

+3

@abest nó vẫn gặp sự cố khi chạy thử nghiệm trên máy mac – jonney

0

Tôi đã giải quyết cùng một lỗi, nhưng theo cách khác. tôi đã sử dụng bóng lớp tùy chỉnh trong các thử nghiệm, Vì vậy, tôi phải tạo lớp TestRunner của riêng tôi, như thế này:

public class MyRobolectricTestRunner extends RobolectricTestRunner { 

    public MyRobolectricTestRunner(Class<?> klass) throws InitializationError { 
     super(klass); 
    } 

    public InstrumentationConfiguration createClassLoaderConfig() { 
     InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); 
     builder.addInstrumentedClass(AppUtils.class.getName()); 
     return builder.build(); 
    } 
} 

Nhưng trên mã chỉ làm việc khi tôi chạy đơn vị kiểm tra từ Andorid studio. Xin vui lòng, kiểm tra mã mà làm việc cho tôi trong cả hai cách: trong Studio và từ dòng lệnh:

public class MyRobolectricTestRunner extends RobolectricTestRunner { 

    public MyRobolectricTestRunner(Class<?> klass) throws InitializationError { 
     super(klass); 
    } 

    @Override 
    public InstrumentationConfiguration createClassLoaderConfig() { 
     InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); 
     builder.addInstrumentedPackage(com.example.stackoverflow.AppUtils.class.getPackage().getName()); 
     return builder.build(); 
    } 
} 

Xin vui lòng, lưu ý tôi phải phụ thuộc:

testCompile 'org.robolectric:robolectric:3.0' 
Các vấn đề liên quan