docs/extending/testing.mdx
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.
This section covers desktop plugins and client plugins.
Flipper uses Jest as a unit testing framework.
Writing unit tests for Flipper Desktop plugins is covered in detail in the Building a Desktop Plugin tutorial.
The flipper-plugin package provide several test utilities to make testing more convenient.
<Tabs defaultValue="android" values={[{label: 'Android', value: 'android'}, { label: 'iOS', value: 'ios'}]}> <TabItem value="android">
<OssOnly>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:
@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:
@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.
#include <MyFlipperPlugin/MyFlipperPlugin.h>
#include <FlipperTestLib/FlipperConnectionMock.h>
#include <FlipperTestLib/FlipperResponderMock.h>
#include <folly/json.h>
#include <gtest/gtest.h>
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:
TEST(MyFlipperPluginTests, testDummy) {
std::vector<folly::dynamic> successfulResponses;
auto responder = std::make_unique<FlipperResponderMock>(&successfulResponses);
auto conn = std::make_shared<FlipperConnectionMock>();
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);
}
This section covers running tests on the Flipper Desktop and with the Flipper SDK.
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
In the root directory of the checkout:
./gradlew android:test
cd fbsource/xplat/sonar
./gradlew android:test
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.
:::
Focus on the plugins, or Flipper code you want but with the --with-tests param:
arc focus ... --with-tests`
Then, click the <-> icon in Xcode and you run from there.
For details, see the Testing React Native Changes page.