Pruebas en subcarpetas de Go: resolviendo el problema del que los tutoriales no hablan
\n\n¿Alguna vez ha escrito pruebas en Go y se ha encontrado con que funcionan perfectamente en la raíz del proyecto, pero al moverlas a una subcarpeta todo se rompe? ¿Le suena familiar? Si es así, no está solo. La pregunta "Golang tests in sub-directory" en Stack Overflow ha acumulado miles de visitas. Y no es de extrañar: la documentación de Go lo explica de manera escueta, y los desarrolladores principiantes a menudo se pierden.
\n\nEn este artículo, analizaremos cómo organizar correctamente las pruebas de Go utilizando paquetes anidados, por qué es necesario y cómo evitar cometer errores. ¡Allá vamos!
\n\n¿Por qué las pruebas en subcarpetas son un problema?
\n\nImagine: tiene un proyecto cuya estructura se ve así:
\n\nmyapp/\n├── main.go\n├── go.mod\n└── utils/\n ├── math.go\n └── math_test.go\n\nEjecuta Go test en la raíz y todo funciona. Pero cuando intenta ejecutar las pruebas desde la carpeta utils, Go se queja: "package myapp/utils is not in GOROOT". ¿Le suena ese error?
El problema es que Go trabaja con paquetes, no con carpetas. Cuando crea una subcarpeta, en realidad está creando un nuevo paquete. Y las pruebas en él deben ejecutarse teniendo en cuenta la estructura modular del proyecto. Pero vayamos por partes.
\n\nConceptos básicos: cómo ve Go las pruebas
\n\nEn Go, las pruebas son archivos comunes con el sufijo _test.go. Pueden estar ubicados:
- \n
- En el mismo paquete (pruebas blancas): tienen acceso a funciones no exportadas. \n
- En un paquete separado con el sufijo
_test(pruebas negras): prueban el paquete como un usuario externo. \n
Cuando coloca las pruebas en una subcarpeta, crea un nuevo paquete. Por ejemplo, la carpeta utils es el paquete utils. Y las pruebas en ella deben pertenecer a ese paquete.
Ejemplo de estructura correcta
\n\nmyapp/\n├── go.mod\n├── main.go\n└── utils/\n ├── math.go // package utils\n └── math_test.go // package utils\n\nEn el archivo math.go:
package utils\n\nfunc Add(a, b int) int {\n return a + b\n}\n\nEn el archivo math_test.go:
package utils\n\nimport "testing"\n\nfunc TestAdd(t *testing.T) {\n result := Add(2, 3)\n if result != 5 {\n t.Errorf("Expected 5, got %d", result)\n }\n}\n\nAhora ejecute las pruebas desde la raíz del proyecto:
\ngo test ./utils/\n\nO desde la carpeta utils:
cd utils\ngo test\n\n¡Todo funciona! Pero, ¿qué sucede si tiene una estructura más compleja?
\n\nSubcarpetas anidadas: más profundo de lo que parece
\n\nSupongamos que tiene un proyecto con esta estructura:
\n\nmyapp/\n├── go.mod\n├── main.go\n└── services/\n ├── user/\n │ ├── user.go\n │ └── user_test.go\n └── order/\n ├── order.go\n └── order_test.go\n\nAquí, cada subcarpeta es un paquete independiente. Para ejecutar todas las pruebas de forma recursiva, use tres puntos:
\n\ngo test ./...\n\nEste comando encontrará todos los paquetes en el proyecto y ejecutará sus pruebas. ¡Muy útil para CI/CD!
\n\n¿Qué pasa si las pruebas están en la misma carpeta que el código?
\n\nA veces los desarrolladores colocan las pruebas en la misma carpeta que el código principal. Esto es normal para proyectos pequeños. Pero para proyectos grandes, es mejor mover las pruebas a subcarpetas separadas: así la estructura se vuelve más limpia.
\n\nErrores típicos y sus soluciones
\n\nAnalicemos los problemas más comunes que enfrentan los principiantes al trabajar con Golang tests in sub-directory.
\n\nError 1: "package is not in GOROOT"
\nCausa: Está intentando ejecutar una prueba desde una subcarpeta sin especificar el módulo. Go no sabe a qué módulo pertenece el paquete.
\nSolución: Asegúrese de tener un archivo go.mod en la raíz