Explicación detallada del esquema general de Flutter Test CI

1. Antecedentes

En el esquema oficial de CI de Flutter Test, hay tres modos de UnitTest/WidgetTest/DriverTest, de los cuales UnitTest/WidgetTest puede ejecutarse en el entorno de pruebas del código, mientras que Driver Test necesita confiar en la construcción del paquete completo; todos saben que en el proceso de prueba unitaria se encuentra que el costo del problema es el más bajo, y la construcción del paquete completo lleva mucho tiempo, por lo que aquí hay una solución general de Flutter Test en la etapa de CI;

La capacidad de detección automática de Flutter CI se construye principalmente a través de la capacidad FlutterTest, pero la construcción de la capacidad de datos específicos es ligeramente insuficiente. La razón principal es que

    1. FlutterTest no admite el envío de una solicitud http directamente;
    1. Y una gran cantidad de datos de canal requiere MOCK activo, si una aplicación grande requiere demasiado simulacro;

Del mismo modo, se puede ver que muchas personas en stackoverflow han preguntado por qué no se puede ejecutar una solicitud de servicio HTTP en el entorno de prueba de aleteo; stackoverflow.com/questions/6…

De hecho, la razón principal del análisis es que en el entorno de prueba de Flutter, muchos códigos en el lado del motor no se pueden ejecutar, lo que hace que el servicio de socket no se pueda enviar normalmente, por lo que el servicio de red se desconecta bajo CI. ; en vista de esto, muchos servicios simulados como flutter mockite brindan una solución es mantener los datos simulados por sí mismos, pero el costo de mantenimiento de este método es muy alto. Todos son programadores y nadie quiere mantener los datos simulados , sin mencionar la situación que el negocio cambia todos los días, la idea principal es cubrirlo a través de setupMockHttpOverrides.Global Http, y luego transferir el servicio de solicitud a la lógica de procesamiento simulado;

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. Esquema

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

imagen.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发现可以正常返回值:

imagen.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更多细节我还没介绍,等后续在开坑介绍~

Supongo que te gusta

Origin juejin.im/post/7119103230251892743
Recomendado
Clasificación