Práctica de construcción de la herramienta de prueba DIFF del servicio de datos basado en GoldenEye PAAS | Equipo técnico de JD Cloud

1. Introducción a los antecedentes

El servicio de datos GoldenEye PAAS es una serie de servicios de datos que implementan el mismo acuerdo de servicio de indicadores. Cada servicio se divide según el tema de los indicadores producidos. Por ejemplo, el servicio de transacciones en tiempo real proporciona la consulta de indicadores de transacciones en tiempo real, y el servicio financiero fuera de línea proporciona la consulta de indicadores financieros fuera de línea. El servicio de datos GoldenEye PAAS respalda las necesidades de consulta de datos de la aplicación GoldenEye, la PC GoldenEye y varias pantallas grandes internas. Para que la empresa pueda tomar decisiones y tomar decisiones correctas sobre los datos, es necesario garantizar la exactitud de los datos proporcionados por los servicios de datos basados ​​en PAAS .

Con la rápida iteración de los requisitos comerciales, los servicios de datos a menudo necesitan ajustar el calibre de las consultas, las dimensiones de las consultas y los indicadores de las consultas, por lo que se necesitan métodos eficientes de pruebas de regresión automatizadas para garantizar la calidad de cada iteración de los requisitos. Las pruebas automatizadas de los servicios de datos PAAS enfrentan algunos problemas:

1. Hay muchos escenarios de consulta: el protocolo de servicio de indicadores admite una gran cantidad de indicadores y dimensiones de consulta, y es difícil que las pruebas manuales cubran todos los escenarios de solicitudes en línea;
2. Parámetros de solicitud complejos: los parámetros de solicitud del protocolo de servicio del indicador son objetos anidados complejos y es difícil para la herramienta Python DIFF existente llamar a la interfaz JSF del servicio de datos a través de http;
3. Es difícil comparar los parámetros de retorno: los parámetros de retorno del protocolo de servicio del indicador utilizan índices para ubicar los valores correspondientes a los nombres de los campos. Si los índices de los campos son inconsistentes o los elementos del conjunto de datos están desordenados , es fácil provocar falsas alarmas en comparación.

En respuesta a la diversidad de escenarios de solicitud y la particularidad del protocolo de servicio del indicador, implementamos una herramienta DIFF dedicada para los servicios de datos GoldenEye PAAS. Al registrar el tráfico en línea, luego reproducirlo en los entornos de prueba y en línea, comparando los resultados devueltos, y Se han optimizado específicamente los problemas de falsos positivos de la eficiencia de reproducción de solicitudes y los resultados de comparación. Este método puede garantizar una cobertura completa de los escenarios de consultas en línea, reducir la intervención manual en la construcción manual de escenarios de solicitudes y proporcionar capacidades de pruebas de regresión automatizadas suficientemente eficientes para potenciar las autopruebas de I+D.

Después de un período de construcción e iteración, la herramienta DIFF del servicio de datos basado en PAAS de GoldenEye ha logrado cobertura de los tres servicios de GoldenEye: comercio en tiempo real, comercio fuera de línea y finanzas fuera de línea, con un recuento de ejecución DIFF mensual promedio de más de 40 veces.

El siguiente artículo presentará los desafíos y las experiencias prácticas encontradas en la construcción de herramientas DIFF del servicio de datos basadas en GoldenEye PAAS.

2. Problemas e ideas

2.1 Dificultades para llamar a los protocolos PAAS

Todos los servicios GoldenEye PAAS implementan el mismo protocolo de servicio de indicador: el parámetro de solicitud es un objeto anidado complejo y cada objeto de condición de filtro en la colección de criterios utiliza la anotación @JsonSubTypes de Jackson para implementar el análisis polimórfico. Según el documento de llamada http del equipo JSF, llamar a una interfaz con objetos anidados complejos requiere agregar "@type": "ruta del paquete + nombre de clase" a cada objeto anidado, y se recomienda usar JSON.toJSONString (instancia, SerializerFeature.WriteClassName ) genera una cadena JSON con características de tipo, como se muestra en la siguiente figura. Antes de la generación, se debe usar Jackson para deserializar los parámetros de solicitud en objetos de instancia. Si insiste en utilizar el método http para llamar a este tipo de interfaz JSF en un script de Python, debe identificar usted mismo la clase de implementación de cada condición de filtro . Para realizar la llamada conveniente a la interfaz JSF del servicio de datos PAAS, nació la herramienta DIFF escrita en Java.



2.2 Principales desafíos

La herramienta DIFF escrita en Java puede resolver el problema de las llamadas a la interfaz del servicio de datos basado en PAAS, pero en el uso real de los scripts DIFF existentes, enfrenta los dos desafíos siguientes:

2.2.1 Solicitar problemas de eficiencia de reproducción

Reproducción de un solo hilo

La llamada a la interfaz y la comparación de resultados de las solicitudes registradas se implementan mediante un único hilo que atraviesa la lista de solicitudes. Después de que una sola solicitud llama con éxito a la interfaz de los entornos en línea y de prueba, los resultados devueltos se comparan. Solo después de que se completa la comparación Simplemente vaya volver a la siguiente solicitud. Pero, de hecho, no existe una secuencia de llamada entre la reproducción de la solicitud anterior y la siguiente. Este método de utilizar un solo subproceso para la reproducción de solicitudes reducirá en gran medida la eficiencia de ejecución y hará que el tiempo de ejecución de la diferencia sea demasiado largo.

Interfaz de llamada síncrona

Además, las llamadas a las interfaces del entorno en línea y de prueba están sincronizadas. Después de que la interfaz de un entorno devuelve un resultado, se llama a la siguiente interfaz. De la misma manera, no existe dependencia entre las llamadas de interfaz de los dos entornos. El valor de retorno de una interfaz de entorno no afectará la llamada de la siguiente interfaz. Solo necesita asegurarse de que ambas llamadas de interfaz de entorno tengan valores de retorno, y luego compare los resultados.

2.2.2 El problema de los falsos positivos en los resultados de comparación

Los índices son inconsistentes

La estructura de parámetros de retorno del protocolo PAAS es la siguiente: se puede ver que el conjunto de datos body.data tiene la mayor cantidad de elementos de información y es el principal objetivo de comparación. El índice de datos meteData.metaIndex define los campos específicos representados por cada valor en los subelementos del conjunto de datos Nombre, por ejemplo, los tres valores en [1234,12345.41,"11068"] representan respectivamente el volumen del pedido principal de la transacción, el monto de la transacción y la identificación de la marca principal. Si los índices de nombres de campos de valor de retorno de las dos interfaces del entorno no son consistentes, pero los valores correspondientes a los nombres de campos realmente obtenidos de acuerdo con el índice son los mismos, en este caso, se atraviesa directamente la subcolección de recopilación de datos para comparar. , obtendrá una conclusión diferente, pero de hecho, los dos valores de retorno son consistentes, lo que lleva a falsos positivos en los resultados de la comparación, como se muestra en la siguiente figura.



matriz desordenada

Además de los índices de nombres de campos inconsistentes, que pueden dar lugar a falsos positivos en la comparación, cada subcolección del conjunto de datos puede estar desordenada. En los datos de parámetros de retorno del ejemplo, la primera subcolección contiene dos indicadores de la marca principal "11068" y la segunda subcolección contiene dos indicadores de la marca principal "231966". Si los datos de parámetros de retorno de otro entorno En la interfaz, la marca principal de una subcolección es "231966" y la marca principal de la segunda subcolección es "11068". El recorrido directo y la comparación en este caso darán lugar a diferencias en los resultados de la comparación, pero de hecho también es un falso positivo.



2.3 Ideas de solución

2.3.1 Concurrencia durante las solicitudes transversales y asincrónica durante la reproducción del tráfico para resolver el problema de la eficiencia de la reproducción de solicitudes

Del análisis del desafío principal, se puede ver que el consumo de tiempo de una ejecución DIFF = el número de solicitudes que deben reproducirse * (el consumo de tiempo de las llamadas a la interfaz en los dos entornos + el consumo de tiempo de comparación) . Se puede ver en la fórmula de división que requiere mucho tiempo que la optimización de la eficiencia de la ejecución DIFF se puede lograr en dos direcciones: solicitar reproducción paralela y llamar a la interfaz asincrónica.

1. Solicitar reproducción paralela: al atravesar la solicitud, envíe la tarea de reproducción y comparación de una sola solicitud al grupo de subprocesos. Una vez completadas las tareas de reproducción y comparación de todas las solicitudes, los datos del resultado de la comparación se resumen y se genera un informe DIFF. ;
2. Llamada asincrónica de interfaz: use CompletableFuture para llamar asincrónicamente a las interfaces de los dos entornos para obtener cf1 y cf2, y luego use el método cf1.thenCombine (cf2) para combinar los resultados de la ejecución de las dos tareas asincrónicas. Después de que ambas tareas asincrónicas sean ejecutado, y luego continúe con el siguiente paso.

2.3.2 Se implementan la unificación del índice de campo y la clasificación secundaria para resolver el problema de los falsos positivos en los resultados de comparación.

Para la estructura de los parámetros de retorno del protocolo PAAS, para lograr cero falsos positivos en los resultados de la comparación, es necesario garantizar la unificación de los índices de campo de valor de retorno de los dos entornos y el orden de las subcolecciones dentro del conjunto de datos. , de modo que al comparar los resultados del valor de retorno, no habrá anomalías de contraste.

La implementación unificada del índice de campo es relativamente simple: según el metaíndice del índice de campo del valor de retorno de una interfaz de entorno, reorganice la posición de cada valor en la subcolección de datos en el valor de retorno de otra interfaz de entorno para garantizar que Se recorre cada valor de la subcolección de datos. , Los nombres de los campos correspondientes son coherentes.

La clasificación secundaria es para resolver el problema de orden entre subconjuntos de datos. La razón por la que se hace hincapié en "secundario" es porque el subconjunto puede contener múltiples valores. Si solo se ordena un valor, el subconjunto no se puede garantizar completamente. Por lo tanto, es necesario implementar un clasificador secundario para seleccionar múltiples valores en el subconjunto como base para la clasificación , de modo que el orden entre los subconjuntos sea estable y garantice la confiabilidad de los resultados de la comparación.

3. Estructura general



4. Puntos centrales de diseño

4.1 Solicitar optimización de la eficiencia de reproducción

4.1.1 Solicitar deduplicación antes de la reproducción

Antes de crear la herramienta DIFF del servicio de datos, uno de los objetivos era " hacer que cada solicitud de reproducción fuera significativa ". Para los servicios de consulta de datos de solo lectura, habrá una gran cantidad de solicitudes repetidas todos los días. Si las solicitudes no se deduplican, una gran parte de las solicitudes de reproducción se repetirán. Dichas solicitudes se utilizarán para reproducción y DIFF, que no Solo desperdicia recursos, interfiriendo con el resumen de los resultados finales de la comparación, todavía no tiene sentido. Por lo tanto, es necesario el procesamiento de deduplicación antes de solicitar la reproducción.

Inicialmente, el método de deduplicación de parámetros de solicitud adoptado por la herramienta DIFF es el método HashSet. Antes de llamar a la interfaz para reproducir el tráfico, la deduplicación de solicitud se guarda en un HashSet. Una vez completada la deduplicación, se recorre el HashSet para reproducir el tráfico y Ejecución DIFF. Aunque este método puede eliminar duplicados de manera efectiva, en el uso real, si la cantidad de solicitudes que requieren diferencias es demasiado grande o los parámetros de la solicitud son demasiado grandes (como consultar los indicadores financieros de 2000 SKU específicos), entonces la eficiencia de deduplicación de HashSet es relativamente bajo, y la deduplicación transversal de 50,000 solicitudes grandes toma más de 10 minutos y ocupa mucha memoria.Si la memoria del contenedor de canalización que ejecuta DIFF es pequeña, la ejecución de DIFF fallará directamente.

Para mejorar la eficiencia de deduplicación de solicitudes, se utiliza el método de filtro Bloom para lograr la deduplicación. La memoria ocupada es menor que el método HashSet y la eficiencia para determinar si hay duplicados también es relativamente alta. Es adecuado para operaciones de deduplicación. de grandes cantidades de datos .

for (int i = 0; i < maxLogSize; i++) {
    String reqParam = fileAccess.readLine();
    if (bloomFilter.mightContain(reqParam)){
        //请求重复,跳过此请求
        countDownLatch.countDown();
        continue;
    }else {
        bloomFilter.put(reqParam);
    }
    //请求不重复,执行接口调用和DIFF    
}

4.1.2 Simultaneidad al atravesar solicitudes

Al atravesar solicitudes, utilice el método ejecutar () para enviar la reproducción de solicitudes y las tareas de ejecución DIFF al grupo de subprocesos. Cada solicitud generará una tarea independiente y las tareas se ejecutarán en paralelo, lo que mejora la eficiencia de ejecución de todo el proceso DIFF. Dado que DIFF necesita realizar el resumen y mostrar las diferencias de comparación después de que se completa cada solicitud de reproducción y comparación de resultados, el hilo principal debe bloquearse y esperar a que finalicen todos los subprocesos de la tarea de comparación de reproducción antes de iniciar el hilo principal para realizar el resumen. análisis de resultados de diferencias.

Para cumplir con los requisitos de tiempo de llamada entre el subproceso principal y el subproceso , se utiliza el contador CountDownLatch. El número máximo de solicitudes n se establece durante la inicialización. Cada vez que finaliza un subproceso, el contador se reduce en uno. Cuando el contador se convierte en 0, el hilo principal que ha estado esperando se despierta y resume los resultados de la diferencia.

Esto nuevamente implica el problema de la política de rechazo del grupo de subprocesos. Si utiliza la política AbortPolicy predeterminada del grupo de subprocesos, pero no detecta excepciones y disminuye el contador en uno durante el manejo de excepciones, cuando el grupo de subprocesos no pueda aceptar nuevas tareas, el contador CountDownLatch nunca será 0, el hilo principal siempre estará bloqueado y el proceso DIFF nunca terminará. Para permitir que DIFF se ejecute sin problemas y genere resultados de comparación en circunstancias anormales, y para garantizar que cada solicitud pueda reproducirse y compararse, CallerRunsPolicy se utiliza aquí para devolver las tareas rechazadas a la persona que llama para su ejecución.

//初始化计数器
CountDownLatch countDownLatch = new CountDownLatch(maxLogSize);
log.info("开始读取日志");
for (int i = 0; i < maxLogSize; i++) {
    String reqParam = asciiFileAccess.readLine();
    if (bloomFilter.mightContain(reqParam)){
        //有重复请求,跳出本次循环,计数器减一    
        countDownLatch.countDown();
        continue;
    }else {
        bloomFilter.put(reqParam);
    }
    //向线程池提交回放和对比任务
    threadPoolTaskExecutor.execute(() -> {
        try {
            //执行接口调用和返回结果对比
            }
        } catch (Exception e) {
        } finally {
            //子线程一次执行完成,计数器减一
            countDownLatch.countDown();
        }
    });
}
//阻塞主线程
countDownLatch.await();
//等待计数器为0后,开始汇总对比结果

4.1.3 Asíncrono al solicitar reproducción

JSF proporciona un método de llamada asíncrona de interfaz, que devuelve un objeto CompletableFuture<T>. Puede utilizar fácilmente el método thenCombine para combinar la interfaz del entorno de prueba y el valor de retorno de la llamada a la interfaz del entorno de prueba, realizar una comparación de los valores de retorno y devolver el resultado de la comparación.

//测试环境接口异步请求
CompletableFuture<UResData> futureTest = RpcContext.getContext().asyncCall(
    () -> geTradeDataServiceTest.fetchBizData(param)
);
//线上环境接口异步请求
CompletableFuture<UResData> future = RpcContext.getContext().asyncCall(
    () -> geTradeDataServiceOnline.fetchBizData(param)
);
//使用thenCombine对futureTest和future执行结果合并处理
CompletableFuture<ResCompareData> resultFuture = futureTest.thenCombine(future, (res1, res2) -> {
//执行对比,返回对比结果
return resCompareData;
});
//获取对比结果的值
return resultFuture.join();

4.2 Optimización de la tasa de falsas alarmas

4.2.1 Unificación del índice de campos

El núcleo de la unificación del índice de campo es encontrar la relación de mapeo entre el mismo índice de nombre de campo entre dos valores de retorno. Por ejemplo, el índice índice1 del nombre de campo a en el valor de retorno A corresponde al índice índice2 del nombre de campo a en el valor de retorno B. . Una vez encontradas todas las relaciones de mapeo, se reorganiza el orden de los campos en la matriz de valores de retorno B.

List<List<Object>> tmp = new ArrayList<>();
int elementNum = metaIndex1.size();
HashMap<Integer, Integer> indexToIndex = new HashMap<>(elementNum);
//获取索引映射关系
for (int i = 0; i < elementNum; i++) {
    String indicator = getIndicatorFromIndex(i, metaIndex2);
    Integer index = metaIndex1.get(indicator);
    indexToIndex.put(i, index);
}
//根据映射关系重新排放字段,生成新的数据集合
for (List<Object> dataElement : data2) {
    List<Object> tmpList = new ArrayList<>();
    Object[] objects = new Object[elementNum];
    for (int i = 0; i < dataElement.size(); i++) {
        objects[indexToIndex.get(i)] = dataElement.get(i);
    }
    Collections.addAll(tmpList, objects);
    tmp.add(tmpList);
}

4.2.2 Clasificación secundaria de conjuntos de datos

Los datos del conjunto de datos contienen múltiples subconjuntos, y cada subconjunto es una combinación de valores de atributos e indicadores. Para lograr el orden entre subcolecciones, es necesario encontrar los índices de todos los campos de atributos e implementar un clasificador secundario que utilice los valores de todos los campos de atributos como criterio de clasificación.

En términos generales, el tipo de datos de los campos de atributo es de tipo Cadena, pero también hay casos especiales. Por ejemplo, si se usa sku_id como valor de atributo, entonces el tipo de datos devuelto por sku_id es de tipo Largo. Para lograr la universalidad y confiabilidad del clasificador secundario, primero use todos los campos de tipo Cadena para ordenar y luego use los campos de tipo Largo para ordenar. Si no hay ningún campo de tipo Cadena, entonces se ordenan todos los campos de tipo Largo.

List<Integer> strIndexList = new ArrayList<>();
List<Integer> longIndexList = new ArrayList<>();
// 保存所有String和Long类型字段的索引
for (int i = 0; i < size; i++) {
    if (data.get(0).get(i) instanceof String) {
        strIndexList.add(i);
    }
    if (data.get(0).get(i) instanceof Long || data.get(0).get(i) instanceof Integer) {
        longIndexList.add(i);
    }
}
//首选依据String类型字段排序
if (!strIndexList.isEmpty()) {
    //初始化排序器
    Comparator<List<Object>> comparing = Comparator.comparing(o -> ((String) o.get(strIndexList.get(0))));
    for (int i = 1; i < strIndexList.size(); i++) {
        int finalI = i;
        //遍历剩余String字段,实现任意长度次级排序器
        comparing = comparing.thenComparing(n -> ((String) n.get(strIndexList.get(finalI))));
    }
    for (int i = 0; i < longIndexList.size(); i++) {
        int finalI = i;
        comparing = comparing.thenComparingLong(n -> Long.parseLong(n.get(longIndexList.get(finalI)).toString()));
    }
    sortedList = data.stream().sorted(comparing).collect(Collectors.toList());
}

4.3 Efecto DIFF del servicio de datos PAAS

Después de optimizar la eficiencia de reproducción de solicitudes y la tasa de falsas alarmas, el consumo de tiempo y los resultados de comparación de una ejecución DIFF del servicio de datos pueden satisfacer las necesidades de las autopruebas y regresiones de I+D existentes antes de conectarse. La siguiente figura muestra un informe DIFF del servicio comercial en tiempo real GoldenEye. Bajo la configuración de cuatro subprocesos de trabajo, después de deduplicar 40.000 solicitudes, la reproducción de la solicitud tardó 570 segundos. Los resultados de la comparación también pueden mostrar claramente las diferencias de datos. Para facilitar la investigación de las diferencias de datos, al mostrar los resultados de la comparación de diferencias, los nombres de los campos se empalman antes de los valores para evitar buscar manualmente los nombres de los campos correspondientes a los valores de diferencias según el índice.



5. Implementación

5.1 Tubería de acceso a pruebas de servicios de datos

La canalización proporciona átomos de código de descarga, átomos de compilación y átomos de script personalizados de Shell. Estos tres átomos pueden desencadenar la ejecución de tareas DIFF. Con la ayuda de esta capacidad del canal, se ha introducido la capacidad de las herramientas DIFF en el canal de acceso de prueba de GoldenEye para el comercio en tiempo real y servicios de datos fuera de línea de GoldenEye. La canalización de acceso a la prueba incluye la compilación y la implementación JDOS de códigos de rama de prueba, la reproducción del tráfico y la comparación de resultados de ejecución, y estadísticas de cobertura de prueba de interfaz durante el proceso DIFF. A través de la reproducción del tráfico en línea para las pruebas DIFF, la cobertura de línea del servicio de transacciones fuera de línea y el código de servicio en tiempo real alcanzaron el 51% y el 65% respectivamente .

Tubería de acceso a pruebas de servicios fuera de línea de transacciones

Tubería de acceso a pruebas de servicios en tiempo real de transacciones

5.2 Autoprueba de I+D del servicio para mejorar la eficiencia

Además de que la herramienta DIFF desempeña un papel en el proceso de acceso a las pruebas, también hemos configurado un canal que puede activar DIFF manualmente para potenciar las autopruebas de I+D y mejorar la eficiencia. En la actualidad, el canal DIFF se ha implementado en múltiples servicios de datos de GoldenEye PAAS, incluido el servicio de transacciones fuera de línea, el servicio de transacciones en tiempo real y el servicio financiero fuera de línea. La siguiente figura muestra los tiempos de ejecución mensual del canal DIFF de estos tres servicios de datos. Los tiempos de ejecución acumulados en septiembre son : 66 veces DIFF .



*Fuente de datos: estadísticas de tendencias de ejecución de canalizaciones

En la actualidad, la herramienta DIFF ya tiene la capacidad de personalizar el umbral de tasa de diferencia, filtrar y excluir palabras clave, y personalizar las condiciones de filtrado y solicitar indicadores para solicitudes PAAS de servicios de indicadores. Esta capacidad de personalización para solicitudes de servicios de indicadores basadas en PAAS desempeña un papel determinado en la iteración diaria de la demanda y la transformación técnica.

Por ejemplo, el motor de consulta de servicios comerciales en tiempo real GoldenEye se cambió de Elasticsearch a Doris, lo que implicó una gran cantidad de trabajo de pruebas de regresión DIFF. Durante este proceso, I+D descubrió que existen algunas diferencias en los métodos de cálculo de Elasticsearch y Doris para los indicadores de deduplicación (como las cantidades de subelementos). Como resultado, la tasa de diferencia de los indicadores de deduplicación consultados utilizando los dos motores será mayor que el de otros indicadores que no son deduplicación (como la cantidad), esto interferirá con la visualización de los resultados finales de la comparación y no favorecerá el descubrimiento de solicitudes verdaderamente diferentes. Para resolver este problema, brindamos la capacidad de personalizar el servicio de indicadores Indicadores de solicitud basados ​​​​en PAAS Puede configurar la solicitud de reproducción para consultar solo indicadores sin deduplicación, evitando la interferencia de los indicadores de deduplicación y promoviendo el progreso de las pruebas de regresión. .

6. Resumen

Este artículo presenta los dos problemas principales de eficiencia DIFF y confiabilidad de los resultados de comparación que enfrentó el equipo de calidad de datos de GoldenEye durante la construcción de la herramienta DIFF del servicio de datos. También detalla las soluciones y la experiencia práctica en la implementación de los dos tipos de problemas anteriores y sus correspondientes. desafíos respectivamente.

6.1 Ventajas de las herramientas DIFF personalizadas

En comparación con la plataforma interna de grabación y reproducción profesional R2 de JD.com, nuestra herramienta DIFF es muy insuficiente o inexistente en términos de registro de tráfico, seguimiento de enlaces, versatilidad y otras capacidades. Sin embargo, desde la perspectiva de la personalización DIFF del servicio de datos PAAS, la optimización realizada por nuestra herramienta DIFF en el proceso de personalización y comparación de solicitudes no es compatible actualmente con esta plataforma universal.

6.2 Perspectivas de futuro

En la actualidad, la herramienta DIFF se utiliza para pruebas de regresión automatizadas. La tasa de cobertura de línea de código de las pruebas de interfaz del servicio comercial fuera de línea y del servicio en tiempo real de GoldenEye es de aproximadamente 50%, lo que muestra que los escenarios de consultas diarias en línea no pueden cubrir todas las ramas del código. Para mejorar la cobertura de la línea de código de la prueba DIFF, consideraremos analizar el informe de cobertura más adelante para descubrir los escenarios no cubiertos por la consulta en línea y formar un conjunto fijo de casos de uso de solicitud. respaldar tanto el tráfico en línea como los casos de uso de solicitudes fijas. Configurado para mejorar la cobertura de filas de las pruebas DIFF.

Autor: JD Retail Lei Shiqi

Fuente: Comunidad de desarrolladores de JD Cloud Indique la fuente al reimprimir

Lei Jun: La versión oficial del nuevo sistema operativo de Xiaomi, ThePaper OS, ha sido empaquetada. La ventana emergente en la página de lotería de la aplicación Gome insulta a su fundador. Ubuntu 23.10 se lanza oficialmente. ¡También podrías aprovechar el viernes para actualizar! Episodio de lanzamiento de Ubuntu 23.10: La imagen ISO fue "retirada" urgentemente debido a que contenía discurso de odio. Un estudiante de doctorado de 23 años solucionó el "error fantasma" de 22 años en Firefox. Se lanzó el escritorio remoto RustDesk 1.2.3. Wayland mejorado para soportar TiDB 7.4 Lanzamiento: Oficial Compatible con MySQL 8.0. Después de desconectar el receptor USB Logitech, el kernel de Linux falló. El maestro usó Scratch para frotar el simulador RISC-V y ejecutó con éxito el kernel de Linux. JetBrains lanzó Writerside, una herramienta para la creación de documentos técnicos.
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4090830/blog/10120050
Recomendado
Clasificación