Cómo escribir pruebas unitarias en Rust para tu aplicación de Compute
¿Cómo podemos saber si funcionan nuestras aplicaciones del edge? Estoy a rebosar de confianza cuando escribo código, pero a veces la realidad no está a la altura de mis ensoñaciones, y es por eso que también escribo pruebas para el código.
Con Compute de Fastly, puedes crear aplicaciones de gran escala repartidas por todo el mundo y ejecutar código en el edge. Hoy escribiremos unas cuantas pruebas unitarias para una aplicación Rust usando Viceroy, que permite realizar pruebas locales en entornos de Compute.
Ejecución de una aplicación
Empecemos instalando la CLI de Fastly, así como Rust. En un nuevo directorio, configura un nuevo kit de inicio básico de Rust que demuestre el enrutamiento y respuestas sintéticas simples:
fastly compute init
Elige Rust como lenguaje, además del kit de inicio predeterminado de Rust.
Esto genera una aplicación funcional situada en el directorio, mientras que la lógica principal tiene lugar en src/main.rs.
Para crear y ejecutar esta aplicación en el entorno local, ejecuta el siguiente código:
fastly compute serve
...
INFO: Listening on http://127.0.0.1:7676
Al visitar http://127.0.0.1:7676, deberías ver una simpática página que te confirmará que todo fue sobre ruedas.
Pruebas de la aplicación
Parece que el código funciona, pero ahora toca escribir pruebas para comprobar que todo va como es debido.
Instalemos Viceroy, que nos permitirá ejecutar las pruebas en nuestro entorno local, y también cargo-nextest, que realizará las pruebas en su propia instancia de Wasm para luego combinar los resultados.
Añade el siguiente código al .cargo/config de tu proyecto:
[target.wasm32-wasi]
runner = "viceroy run -C fastly.toml -- "
Tenemos que volver a escribir la función principal de src/main.rs para poder someterla a pruebas, y la cambiamos a:
fn main() -> Result<(), Error> {
let ds_req = Request::from_client();
let us_resp = handler(ds_req)?;
us_resp.send_to_client();
Ok(())
}
fn handler(req: Request) -> Result<Response, Error> {
...
Ahora podemos escribir pruebas sencillas que usen la caja fastly.
Existen tres principales áreas que podemos someter a pruebas:
la lógica que rechaza métodos inesperados;
la lógica que devuelve la respuesta sintética;
la lógica que devuelve un código de estado 404.
Por cada una de estas áreas, enviaremos una petición y comprobaremos el código de estado, tipo de contenido y cuerpo de la respuesta. Añade estas funciones al final del archivo:
#[test]
fn test_post() {
let req = fastly::Request::post("http://example.com/");
let resp = handler(req).expect("request succeeds");
assert_eq!(resp.get_status(), StatusCode::METHOD_NOT_ALLOWED);
assert_eq!(resp.get_content_type(), Some(mime::TEXT_PLAIN_UTF_8));
assert_eq!(resp.into_body_str(), "This method is not allowed\n");
}
#[test]
fn test_homepage() {
let req = fastly::Request::get("http://example.com/");
let resp = handler(req).expect("request succeeds");
assert_eq!(resp.get_status(), StatusCode::OK);
assert_eq!(resp.get_content_type(), Some(mime::TEXT_HTML_UTF_8));
assert!(resp.into_body_str().contains("Welcome to Compute@Edge"));
}
#[test]
fn test_missing() {
let req = fastly::Request::get("http://example.com/missing");
let resp = handler(req).expect("request succeeds");
assert_eq!(resp.get_status(), StatusCode::OK);
assert_eq!(resp.get_content_type(), Some(mime::TEXT_PLAIN_UTF_8));
assert_eq!(
resp.into_body_str(),
"The page you requested could not be found\n"
);
}
Podemos efectuar pruebas con cargo nextest run. Si se nos cuela algún error en el controlador, puede que aparezca un mensaje como el siguiente, que indica que se esperaba un código de estado 404 pero se recibió un código 200:
cargo nextest run
...
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `404`,
right: `200`', src/main.rs:122:5
Canceling due to test failure: 0 tests still running
------------
Summary [ 3.125s] 5 tests run: 4 passed, 1 failed, 0 skipped
FAIL [ 3.122s] fastly-compute-project::bin/fastly-compute-project test_missing
error: test run failed
Con todo, hoy por hoy nuestro controlador no presenta errores y funciona como es debido. Las pruebas, pues, arrojan un cuadro positivo:
cargo nextest run
...
Starting 3 tests across 1 binary
PASS [ 1.596s] fastly-compute-project::bin/fastly-compute-project test_post
PASS [ 1.885s] fastly-compute-project::bin/fastly-compute-project test_homepage
PASS [ 1.900s] fastly-compute-project::bin/fastly-compute-project test_missing
------------
Summary [ 1.902s] 3 tests run: 3 passed, 0 skipped
Demás probaturas
Ahora ya sabes cómo va esto de someter aplicaciones de Compute en Rust a pruebas unitarias. ¿Qué más puedes hacer? Aconsejo dividir toda lógica compleja en funciones pequeñas que se puedan someter a pruebas. Si te atrae la idea, ¿por qué no escribes las pruebas antes de escribir la propia función? ¡A probar! Y si aún no usas nuestra plataforma sin servidores, lánzate a explorar Compute a fondo y totalmente gratis.