c# - unitarias - El explorador de prueba VS2012 bloquea el.dll nativo, lo que hace que las reconstrucciones fallen
unit test c# visual studio 2015 (6)
Estoy usando Visual Studio 2012 para una solución con C # y C ++ / CLI .dll, con el dll de C ++ / CLI haciendo referencia a .dlls nativos como boost. El código de C ++ se compila como x64.
Cuando abro VS, puedo limpiar y construir mi proyecto.
Utilizando Test Explorer, puedo ejecutar mis pruebas.
Tan pronto como utilicé Test Explorer para ejecutar pruebas una vez, no puedo reconstruir el proyecto. Parece que VS2012 Test Explorer mantiene un bloqueo en mi C ++ / CLI-dll, y ahí aparece el siguiente error:
LNK1104: cannot open file ''C:/Dev/LockExample/bin/Debug/cli.dll''
Como resultado de esto, cada vez que ejecuto las pruebas con Test Explorer, necesito reiniciar VS2012 antes de poder seguir desarrollando. Obviamente, este no es un proceso de desarrollo sostenible.
Las pruebas y la reconstrucción funcionan sin problemas con C # -sólo dlls- por lo que puedo decir, el problema solo ocurre con las DLL que usan el código x64 nativo.
Después de algunas pruebas más, encontré que el villano aquí es vstest.executionengine.exe. Usando handle (desde SysInternals), veo que vstest.executionengine.exe mantiene bloqueos para .dll y .pdb de cli-dll. No contiene bloqueos para dlls gestionados solamente.
¿Cómo puedo hacer que Visual Studio Test Explorer libere los bloqueos en las DLL de C ++ / Cli después de que se completen las pruebas?
Agregando algunas cosas a la respuesta de @frodesto, (en el caso de VS2013), la configuración de "Prueba> Configuración de prueba> Mantener prueba ejecutar en el motor en ejecución" se almacena en la configuración del usuario (archivo SUO). Esto puede ser un poco desagradable en caso de que ocurra este error en el agente de compilación de TFS, ya que utiliza un usuario predeterminado del servicio.
Para solucionar este caso, primero elimine el archivo vstest.executionengine.exe existente, modifique el usuario utilizado por el agente de compilación TFS para ejecutarlo con el usuario con el que inició sesión. Abra la solución almacenada en el espacio de trabajo del agente de compilación TFS y anule la selección de la opción. Después de eso, el agente de compilación de TFS leerá la opción "mantener el motor de ejecución de prueba" porque el archivo SUO es para el mismo usuario.
Después de buscar un poco más, encontré esta publicación en connect.microsoft.com . La última sugerencia de soluciones alternativas resuelve el problema, aunque es un hack feo.
Puedo reconstruir si agrego lo siguiente como eventos de precompilación a mi DLL de C ++ / CLI:
taskkill /F /IM vstest.executionengine.exe /FI "MEMUSAGE gt 1"
taskkill /F /IM vstest.executionengine.x86.exe /FI "MEMUSAGE gt 1"
Esto matará el proceso vstest.executionengine.exe, liberando así el bloqueo en mi archivo .dll.
En Visual Studio 2013 este problema puede solucionarse fácilmente deseleccionando la opción "Mantener ejecutándose el motor de ejecución de prueba" en "Prueba -> Configuración de prueba" en el menú.
Encontré la respuesta en otra publicación: vstest.executionengine.x86.exe no se cierra
Había escrito una utilidad de C # para poder cargar y descargar bibliotecas nativas here Lo usé en el proyecto de prueba de la siguiente manera. Como descarga dll en Dispose, no obtengo errores de compilación.
public interface INativeCrypto : INativeImport
{
[ImportFunction("mynative.dll"]
int NativeMethod();
}
[TestClass]
public class UnitTest1
{
public void TestMethod1()
{
INativeCrypto impl = NativeImport.Create<INativeCrypto>("");
// Use methods in impl
int i = impl.NativeMethod();
//...
}
}
También he estado combatiendo este problema y al principio usé la solución alternativa "taskkill", pero acabo de tropezar con una opción en la configuración de VS2013 que parece resolver este problema de manera más elegante:
Eliminar la marca de verificación en el
Mantenga el motor de ejecución de prueba ejecutándose entre ejecuciones de prueba
opción encontrada en
Herramientas / Opciones / Herramientas de prueba de rendimiento web
También me he encontrado con este problema al probar dlls nativos. La solución alternativa (¿solución?) Que encontré fue agregar un DeploymentItemAttribute a las pruebas; no estoy seguro si esto es cierto en general, pero ciertamente funcionó para mí. Es un poco molesto si hay muchos (tuve 6 en mi caso), pero una vez hecho esto, fue fácil copiar y pegar en las otras pruebas.
Entonces mi clase de prueba de unidad se ve así:
[TestClass]
public class TestMyClass
{
[TestMethod]
[DeploymentItem("firstnative.dll")]
[DeploymentItem("secondnative.dll")]
public void TestMyMethod()
{
//Code which (indirectly) uses the above native dlls.
}
}