-
Notifications
You must be signed in to change notification settings - Fork 101
Testing guidelines
Within the CM build system, you can manually generate code coverage reports by leveraging the CTS api coverage mechanism. This allows you to view the current test coverage within the cmsdk's test package for all public interfaces that are defined in the api stubs.
To invoke, make the target for cmsdk test coverage from the root of the tree:
make cmsdk-test-coverage
The resulting html page will be within $OUT/host/<host arch>/cmsdk-api-coverage
as test-coverage.html
Likewise, you can view the routinely updated and hosted test coverage here: CMSDK Test Coverage
Since we need to maintain compatibility with respect to variances in CMSDK vs CM Framework versions, and we can't rely on runtime stubs like AOSP, we've adopted a "header" for any parcels which are sent over IPC. This header is fairly straightforward and is generously borrowed from the implementation in DashClock.
Since we rely so heavily on making sure that custom objects can pass over IPC correctly, our testing paradigms needs to enforce this.
A quick example is shown (from):
@SmallTest
public void testCustomTileOnSettingsClickIntentUnravelFromParcel() {
Intent intent = new Intent(mContext, DummySettings.class);
CustomTile expectedCustomTile = new CustomTile.Builder(mContext)
.setOnSettingsClickIntent(intent)
.build();
// Write to parcel
Parcel parcel = Parcel.obtain();
expectedCustomTile.writeToParcel(parcel, 0);
// Rewind
parcel.setDataPosition(0);
// Verify data when unraveling
CustomTile fromParcel = CustomTile.CREATOR.createFromParcel(parcel);
assertNotNull(fromParcel.onSettingsClick);
assertEquals(expectedCustomTile.onSettingsClick.toString(),
fromParcel.onSettingsClick.toString());
}
As you can see, we populate the members we want to test when sending over IPC. Instead of directly sending the parcel over IPC, and mocking out way too many things, we cheat a bit. Take the custom object, write it to a parcel, rewind the parcel to its original data position and leverage the custom objects CREATOR to recreate a new Object for comparison.
The common builder pattern is tested mostly the same way (we're essentially just testing that the builders .build()
invocation actually gives us the data we want.
@SmallTest
public void testCustomTileBuilderOnClickIntent() {
Intent intent = new Intent(Intent.ACTION_DIAL);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
CustomTile customTile = new CustomTile.Builder(mContext)
.setOnClickIntent(pendingIntent)
.build();
assertNotNull(customTile.onClick);
assertEquals(pendingIntent, customTile.onClick);
}
The above assertion simply tests that the pending intent we're passing in actually comes out of the built custom tile object as expected.
The simplest test is to verify that your service is set up correctly and will be exposed to third parties during runtime on CyanogenMod.
A brief example here:
@SmallTest
public void testManagerServiceIsAvailable() {
ICMStatusBarManager icmStatusBarManager = mCMStatusBarManager.getService();
assertNotNull(icmStatusBarManager);
}
The above test does a simple call to the CMStatusBarManager to retrieve its bound service, stores it within the AIDL where the interface is defined, and verifies that the object isn't null.