--- id: testing title: Testing --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import FbIosTesting from '../fb/_ios-plugin-development-testing-ios-plugins-0.mdx'; import FbAndroidTesting from '../fb/_android-plugin-development-testing-android-plugins-0.mdx'; Developer tools are only used if they work. Testing is important as it discovers defects/bugs and improves the quality, reliability and functionality of software. This page details the Flipper APIs that can be used to effectively test plugins. ## Writing tests This section covers [desktop plugins](#desktop-plugins) and [client plugins](#client-plugins). ### Desktop plugins Flipper uses [Jest](https://jestjs.io/) as a unit testing framework. Writing unit tests for Flipper Desktop plugins is covered in detail in the [Building a Desktop Plugin](../../docs/tutorial/js-custom.mdx#testing-plugin-logic) tutorial. The `flipper-plugin` package provide several [test utilities](../../docs/extending/flipper-plugin.mdx#testutils) to make testing more convenient. ## Client plugins Start by creating your first test file in this directory `MyFlipperPluginTest.java`. In the test method body, is the plugin to be tested as well as a `FlipperConnectionMock`. The following example asserts that the plugin's connected status is what is expected: ```java @RunWith(RobolectricTestRunner.class) public class MyFlipperPluginTest { @Test public void myTest() { final MyFlipperPlugin plugin = new MyFlipperPlugin(); final FlipperConnectionMock connection = new FlipperConnectionMock(); plugin.onConnect(connection); assertThat(plugin.connected(), equalTo(true)); } } ``` There are two mock classes that are used to construct tests: `FlipperConnectionMock` and `FlipperResponderMock`. Together these can be used to write very powerful tests to verify the end-to-end functionality of your plugin. For example, you can test if, for a given incoming message, your plugin responds as expected: ```java @Test public void myTest() { final MyFlipperPlugin plugin = new MyFlipperPlugin(); final FlipperConnectionMock connection = new FlipperConnectionMock(); final FlipperResponderMock responder = new FlipperResponderMock(); plugin.onConnect(connection); final FlipperObject params = new FlipperObject.Builder() .put("phrase", "flipper") .build(); connection.receivers.get("myMethod").onReceive(params, responder); assertThat(responder.successes, hasItem( new FlipperObject.Builder() .put("phrase", "ranos") .build())); } ``` Start by creating your first test file `MyFlipperPluginTests.cpp` and import the testing utilities from `fbsource//xplat/sonar/xplat:FlipperTestLib`. These utilities mock out core pieces of the communication channel so that you can test your plugin in isolation. ```objc #include #include #include #include #include namespace facebook { namespace flipper { namespace test { TEST(MyFlipperPluginTests, testDummy) { EXPECT_EQ(1 + 1, 2); } } // namespace test } // namespace flipper } // namespace facebook ``` Following is a simple test using these mock utilities to create a plugin, send some data, and assert that the result is as expected: ```objc TEST(MyFlipperPluginTests, testDummy) { std::vector successfulResponses; auto responder = std::make_unique(&successfulResponses); auto conn = std::make_shared(); MyFlipperPlugin plugin; plugin.didConnect(conn); folly::dynamic message = folly::dynamic::object("param1", "hello"); folly::dynamic expectedResponse = folly::dynamic::object("response", "Hi there"); auto receiver = conn->receivers_["someMethod"]; receiver(message, std::move(responder)); EXPECT_EQ(successfulResponses.size(), 1); EXPECT_EQ(successfulResponses.back(), expectedResponse); } ``` ## Running (Flipper) tests This section covers running tests on the [Flipper Desktop](#flipper-desktop) and with the [Flipper SDK](#flipper-sdk). ### Flipper Desktop Run `yarn jest` or `yarn jest --watch` in the `desktop` directory of your Flipper checkout. Run `yarn jest` or `yarn jest --watch` in `~/fbsource/xplat/sonar/desktop` ### Flipper SDK #### Android (Java) ##### Gradle In the root directory of the checkout: ```sh ./gradlew android:test ``` ##### Gradle ```sh cd fbsource/xplat/sonar ./gradlew android:test ``` ##### Buck Make the required changes then submit a diff. With regarding to testing, `buck test ...` should work, but doesn't seem to function when run in xplat on a Mac; it does function on Mobile On Demand if you use @mode/server. :::note Debugging note Things do functtion if you copy the files and BUCK file to `fbandroid/javatests` and change the rule from `sonar_android_test` to `robolectric3_test`. ::: ### iOS Focus on the plugins, or Flipper code you want but with the `--with-tests` param: ```sh arc focus ... --with-tests` ``` Then, click the '<->' icon in xcode and you run from there. ### React Native For details, see the [Testing React Native Changes](testing-rn.mdx) page.