55import org .junit .runners .Parameterized ;
66import org .junit .runners .Parameterized .Parameters ;
77
8+ import java .util .Arrays ;
89import java .util .Collection ;
9- import java .util .ArrayList ;
10+ import java .util .Objects ;
11+ import java .util .stream .Collectors ;
1012
1113import static org .junit .Assert .assertTrue ;
1214
15+ /// On-device native test runner for Android instrumentation tests.
16+ ///
17+ /// Executes native C/C++ unit tests bundled in the APK via the Android NDK testing framework.
18+ /// Each native test is discovered at runtime and run as a separate JUnit parameterized test.
19+ ///
20+ /// @note Follows Android’s official on-device native testing guidance:
21+ /// https://developer.android.com/ndk/guides/test-native-libraries
22+ /// https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests
23+ ///
24+ /// @see https://developer.android.com/ndk/guides/test-native-libraries
25+ /// @see https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests
1326@ RunWith (Parameterized .class )
14- public class AppActivityTest {
27+ public final class AppActivityTest {
1528
1629 static {
1730 System .loadLibrary ("tests" );
1831 }
1932
33+ /// Retrieves the list of available native test names.
34+ ///
35+ /// Queries the embedded native test suite for registered test identifiers.
36+ /// Used to populate JUnit parameterized instances.
37+ ///
38+ /// @return Array of native test names, or null if unavailable
2039 public static native String [] getTestNames ();
40+
41+ /// Executes a specific native test by name.
42+ ///
43+ /// @param name Test identifier to run
44+ /// @return true if passed, false otherwise
2145 public static native boolean runTest (String name );
2246
47+ /// The name of the current test case being executed.
2348 @ Parameterized .Parameter
2449 public String testName ;
2550
51+ /// Provides test parameters for JUnit's parameterized runner.
52+ ///
53+ /// Safely handles null or empty native test lists to avoid runtime errors.
54+ ///
55+ /// @return Collection of test name parameters; empty if no tests found
2656 @ Parameters (name = "{0}" )
2757 public static Collection <Object []> data () {
28- try {
29- String [] testNames = getTestNames ();
30-
31- Collection <Object []> result = new ArrayList <>();
32- for (String name : testNames ) {
33- result .add (new Object []{name });
34- }
35- return result ;
36- } catch (Exception e ) {
37- Collection <Object []> fallback = new ArrayList <>();
38- fallback .add (new Object []{"mock_test_error" });
39- return fallback ;
40- }
58+ final String [] names = Objects .requireNonNull (getTestNames (),
59+ "Native test names must not be null — check that libtests is loaded and exports a valid test suite." );
60+ return Arrays .stream (names )
61+ .map (name -> new Object []{name })
62+ .collect (Collectors .toList ());
4163 }
4264
65+ /// Executes a single native test case.
66+ ///
67+ /// Asserts that the native test passes; includes test name in failure message.
4368 @ Test
4469 public void runSingle () {
45- assertTrue ("❌ " + testName + " failed" , runTest (testName ));
70+ assertTrue ("❌ Native test ' " + testName + "' failed" , runTest (testName ));
4671 }
47- }
72+ }
0 commit comments