Flutter Test CI의 일반 체계에 대한 자세한 설명

1. 배경

Flutter Test의 공식 CI 체계에는 UnitTest/WidgetTest/DriverTest의 세 가지 모드가 있으며 그 중 UnitTest/WidgetTest는 코드의 샌드박스 환경에서 실행할 수 있는 반면 Driver Test는 전체 패키지 구성에 의존해야 합니다. 단위 테스트 과정에서 문제의 비용이 가장 낮고 전체 패키지 구성에 시간이 오래 걸리는 것으로 나타났으므로 여기 CI 단계에서 Flutter Test의 일반적인 솔루션이 있습니다.

Flutter CI 자동 감지 기능은 주로 FlutterTest 기능을 통해 구축되지만 특정 데이터 기능 구성이 약간 미흡합니다.

    1. FlutterTest는 http 요청을 직접 보내는 것을 지원하지 않습니다.
    1. 큰 응용 프로그램에 너무 많은 모의가 필요한 경우 많은 양의 채널 데이터에는 활성 MOCK가 필요합니다.

마찬가지로 stackoverflow의 많은 사람들이 플러터 테스트 환경에서 HTTP 서비스 요청을 실행할 수 없는 이유를 묻는 것을 볼 수 있습니다( stackoverflow.com/questions/6…

실제로 분석의 주된 이유는 Flutter Test의 샌드박스 환경에서 엔진측의 많은 코드를 실행하지 못하여 소켓 서비스가 정상적으로 전송되지 못하여 CI 하에서 네트워크 서비스가 끊어지기 때문입니다. ; 이에 비추어 볼 때 플러터 모카이트(Flutter Mockite)와 같은 많은 모의 서비스가 제공하는 하나의 솔루션은 모의 데이터를 자체적으로 유지하는 것이지만 이 방법의 유지 비용이 매우 높습니다. , 비즈니스가 매일 바뀌는 상황은 말할 것도 없고, setupMockHttpOverrides.Global Http를 통해 이를 커버한 다음 요청 서비스를 모의 처리 로직으로 전달하는 것이 주요 아이디어입니다.

void setupMockHttpOverrides() {
  HttpOverrides.global = MockHttpOverrides();
}
复制代码
/// mock 模拟 http
class MockClient extends Mock implements http.Client {}
void main() {
    test("testHttp", () async {
      final client = MockClient();
      when(client.get("xxxx"))
          .thenAnswer((_) async {
        return http.Response(
            '{"title": "test title", "body": "test body"}', 200);
      });
      var post = await fetchPost(client);
      expect(post.title, "test title");
    });
复制代码

2. 계획

介绍了上述的那种方案,肯定狗都直摇头,本文主要介绍一种投机方案解决CI服务,我们发现,flutterTest是可以运行一些Dart代码,但是httpClient运行到sky_engine的一些代码逻辑时候就没有返回值,导致无法发送一个http请求出去,但是无意偶然机会发现官方介绍Process,其通过Process.run可以实现一些shell命令:

이미지.png

既然可以运行Shell命令,即可以通过CURL发送一个http请求,在flutterTest环境中发送如下:

 test('httpTest', () async {
    ProcessResult result = await Process.run('curl', [
      'http://www.baidu.com',
    ]);
    String serverResponse = result.stdout();
  });
复制代码

遗憾是实际测试发现在flutterTest环境中运行在Process.run也卡住没有返回值,跟进代码发现有一个同步方式Process.runSyn发现可以正常返回值:

이미지.png

于是乎我们就可以使用Process.runSyn方法通过CURL命令绕过HTTP服务缺陷,发送一个真实的网络服务了;

解决完网络服务,其次就是Channel服务能力,这块官方的推荐方案是:

 MethodChannel('flutter_mock_service').setMockMethodCallHandler((MethodCall methodCall) async {
  if (methodCall.method == 'getPlatformVersionMock') {
    return 'Android 11 Mock';
  }
  return null;
});
复制代码

但是很多大型应用HTTP服务都是从MethodChanenl走到Native发送出去的,因此如果HTTP服务都需要自己MOCK,那单测写死的心都有了,在我上一篇文章介绍Flutter 构建PlayGround极速方案有介绍如何HOOK MethodChanenl,并且在宿主APP开启一个网络服务能力,我们完全可以使用CURL将Channel的服务打到宿主APP上,然后通过此方式就可以快速MOCK出任何Channel服务能力;

个人已经实现一个flutter 2.5.x版本的插件方案,欢迎白嫖flutter_mock_service

3. 扩展

本文主要介绍了在FlutterTest环境下如何通过CURL方案可以HOOK住 HTTP服务以及MethodChannel服务,但是flutter_mock_service更多细节我还没介绍,等后续在开坑介绍~

рекомендация

отjuejin.im/post/7119103230251892743
рекомендация