Flutter le permite escribir pruebas simples y directas para diferentes partes de su aplicación.
Hoy intentaremos escribir varias pruebas unitarias que se utilizan para probar clases, métodos y funciones individuales.
También intentaremos utilizar una biblioteca Mockito
que le permita crear implementaciones falsas.
Bueno, ¡comencemos a probar!
Nuestro plan
Parte 1 - introducción al desarrollo, primer apéndice, concepto de estado;
Parte 2 : archivo pubspec.yaml y uso de flutter en la línea de comandos;
Parte 3 - BottomNavigationBar y Navigator;
Parte 4 - MVC. Usaremos este patrón en particular como uno de los más simples;
Parte 5 : paquete http. Creación de la clase Repository, primeras solicitudes, listado de publicaciones;
Parte 6 : trabajar con formularios, cuadros de texto y crear una publicación.
Parte 7 : trabajar con imágenes, mostrar imágenes en forma de cuadrícula, recibir imágenes de la red, agregar las suyas a la aplicación;
Parte 8 : creación de su propio tema, agregando fuentes y animaciones personalizadas;
Parte 9 (artículo actual): un poco sobre pruebas;
Agregar las dependencias requeridas
Necesitamos dos paquetes adicionales mockito
y build_runner
, por lo tanto, los agregamos:
# # dev_dependencies: flutter_test: sdk: flutter mockito: ^5.0.10 build_runner: ^2.0.4
Ahora podemos empezar a probar
Escribiendo la primera prueba
Habrá una pequeña clase como objeto de prueba Stack
:
class Stack<T> {
final stack = <T>[];
void push(T t) {
stack.add(t);
}
T? pop() {
if (isEmpty) {
return null;
}
return stack.removeLast();
}
bool get isEmpty => stack.isEmpty;
}
Tenga en cuenta: la clase Stack
es genérica.
Hay una carpeta de test,
prueba en el directorio raíz de nuestro proyecto..
Creemos un nuevo archivo en él stack_test.dart
:
import 'package:flutter_test/flutter_test.dart';
import 'package:json_placeholder_app/helpers/stack.dart';
void main() {
//
group("Stack", () {
//
test("Stack should be empty", () {
// expect
//
// ,
expect(Stack().isEmpty, true);
});
test("Stack shouldn't be empty", () {
final stack = Stack<int>();
stack.push(5);
expect(stack.isEmpty, false);
});
test("Stack should be popped", () {
final stack = Stack<int>();
stack.push(5);
expect(stack.pop(), 5);
});
test("Stack should be work correctly", () {
final stack = Stack<int>();
stack.push(1);
stack.push(2);
stack.push(5);
expect(stack.pop(), 5);
expect(stack.pop(), 2);
expect(stack.isEmpty, false);
});
});
}
¡Bastante simple! ¿No lo es?
De hecho, este es un tipo de prueba llamada unidad.
Flutter también admite:
Prueba de widget
Pruebas de integración
En este artículo, solo cubriremos las pruebas unitarias.
Ejecutemos nuestras pruebas con el comando flutter test test/stack_test.dart:
¡Exitosamente!
Prueba de recuperación posterior
Primero, modifiquemos el método fetchPosts
:
Future<PostList> fetchPosts({http.Client? client}) async {
// URL,
//
final url = Uri.parse("$SERVER/posts");
// GET
final response = (client == null) ? await http.get(url) : await client.get(url);
//
if (response.statusCode == 200) {
//
// json.decode
return PostList.fromJson(json.decode(response.body));
} else {
//
throw Exception("failed request");
}
}
Ahora pasemos a escribir la prueba en sí.
Usaremos mockito
para crear http.Client'
un falso
Creemos un archivo post_test.dart
en la carpeta tests
:
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:json_placeholder_app/data/repository.dart';
import 'package:json_placeholder_app/models/post.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
//
import 'post_test.mocks.dart';
// mockito
@GenerateMocks([http.Client])
void main() {
//
final repo = Repository();
group("fetchPosts", () {
test('returns posts if the http call completes successfully', () async {
//
final client = MockClient();
//
when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/posts')))
.thenAnswer((_) async => http.Response('[{"userId": 1, "id": 2, "title": "Title", "content": "Content"}]', 200));
// fetchPosts
//
final postList = await repo.fetchPosts(client: client);
expect(postList, isA<PostList>());
expect(postList.posts.length, 1);
expect(postList.posts.first.title, "Title");
});
test('throws an exception if the http call completes with an error', () {
final client = MockClient();
//
when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/posts')))
.thenAnswer((_) async => http.Response('Not Found', 404));
//
expect(repo.fetchPosts(client: client), throwsException);
});
});
}
Antes de comenzar la prueba, debe generar un post_test.mocks.dart
archivo:
flutter pub run build_runner build
Después de eso, ejecutamos nuestras pruebas con el comando flutter test test/post_test.dart
:
¡Voila!
Conclusión
Hemos cubierto uno de los tipos de prueba más simples y conocidos: la unidad.
Como ya se señaló, Flutter le permite probar widgets por separado, así como realizar pruebas completas mediante pruebas de integración.
Enlaces útiles:
-
Introducción a las pruebas unitarias
Simulacros de dependencias usando Mockito
Prueba de las aplicaciones de Flutter
¡Buen código para todos!