Evite que la 'prueba de trufa' invoque 'despliegue de trufa (migrar)'

Parece que truffle testautomáticamente invoca truffle deploy(aka truffle migrate).

En lo que a mí respecta, estas dos funcionalidades no tienen ninguna relación.

Así que, para empezar, no puedo entender por qué Truffle funciona de esta manera.

Los documentos no parecen mencionar nada sobre este tema.

Me gustaría usar truffle testpara una cosa y truffle deploypara otra cosa.

¿Hay alguna forma de "decir" truffle testpara evitar correr truffle deploy?

¡¡¡Gracias!!!

En uno de sus comentarios a continuación, parece sugerir que ha resuelto esto. ¿Podría proporcionar detalles sobre cómo, por favor?
@glowkeeper: Se explica en ese mismo comentario.
no realmente, ¿alguna posibilidad de que puedas compartir alguna configuración?
¡Ajá, creo que he resuelto esto! En el script de implementación: ``` if ( network === 'rinkeby' ) { return } ``` Entonces, en el script de prueba: ``` this.contract = await BlahContract.at('0x48B98faB029Cd2c77afA780Ab94c2d4e2f4879dA'); ``` Luego ejecuta: truffle test --network rinkeby ```
@glowkeeper: lo agregué como respuesta (ya que es demasiado largo para publicarlo como comentario).

Respuestas (5)

También me encontré con este problema y, de hecho, es el comportamiento previsto de la prueba de trufa: el comportamiento de la sala limpia. Cada ejecución de prueba de trufa redistribuye los contratos. Si no fuera así, el estado guardado de una ejecución anterior podría afectar los resultados de una ejecución posterior, lo que haría que su conjunto de pruebas no fuera determinista.

Pero quería preservar el estado entre las ejecuciones de la prueba de trufa. La forma sugerida de hacer esto está documentada como:

deployment.deploy(Contrato, {sobrescribir: falso})

Desafortunadamente, lo anterior parece fallar en truffle 5.0.1 debido a un error de análisis. Entonces, una solución para forzar el análisis correcto es esta:

deployment.deploy(Contrato, {gas: 6720000, sobrescribir: falso})

https://truffleframework.com/docs/truffle/testing/testing-your-contracts#clean-room-environment

Entorno de sala limpia

Truffle proporciona un entorno de sala limpia al ejecutar sus archivos de prueba. Al ejecutar sus pruebas contra Ganache o Truffle Develop, Truffle utilizará funciones avanzadas de instantáneas para garantizar que sus archivos de prueba no compartan el estado entre sí. Cuando se ejecuta contra otros clientes de Ethereum como go-ethereum, Truffle volverá a implementar todas sus migraciones al comienzo de cada archivo de prueba para garantizar que tenga un nuevo conjunto de contratos para probar.

Buena respuesta, pero sería aún mejor si se vinculara a ese error de análisis para ver cuál es el estado/soluciones alternativas/etc.

Es realmente vergonzoso, cuán estrechos de miras piensan los autores de la trufa. Mis pruebas ejecutan su propia implementación que se usa en las pruebas. En mi caso, la migración de trufas incluye los pasos en los que los datos se copian de la instancia anterior a la nueva instancia del contrato principal, luego se destruye el contrato anterior. Desafortunadamente, aquí la instantánea no ayuda, la instancia anterior no se restaura y permanece una instancia defectuosa en el archivo json del contrato. Así que tengo que evitar que se ejecuten los scripts de migración. Entonces, hay buenas razones por las que la migración debería ser opcional y configurable en truffle test!

Lo resolví de la siguiente manera:

  • ejecutar un segundo canache-clicon una red separada llamadatest
  • si el truffle migratescript está en la red test, no haga nada
  • ejecutar truffle testcon opción--network test

En detalle:

Añadir en la parte superior de migrations/2_contractla línea:

module.exports = async function(deployer, network, accounts) {
  if (network == "test") return; // test maintains own contracts
}

Agregar nueva red testa truffle-config.js:


networks: {
  development: {
    host: "127.0.0.1",
    port: 8545,
    network_id: "*"
  },
  test: {
    host: "127.0.0.1",
    port: 8546,
    network_id: "*"
  }
}

Ejecute un segundo canache-cli(además del que ejecuta la red development:

En una consola, ejecuto ganache developmentpara mis pruebas de GUI:

ganache-cli -d --db ${HOME}/tmp/ganache/development -i 123456 -p 8545

En otra consola, ejecuto un ganache separado para test:

ganache-cli -d --db ${HOME}/tmp/ganache/test -i 654321 -p 8546

¡Eso es! Ahora puedo ejecutar:

truffle migrate --reset

Y

truffle test --network test

Sin interferencias.

Creo que es injusto llamar a los creadores de trufas "de mente estrecha".

La truffle testlínea de comandos utiliza la developmentconfiguración de red.

En otras palabras, es de hecho equivalente a truffle test network=development.

Entonces resolví este problema agregando cada uno de los scripts de migración en mi proyecto:

module.exports = function(deployer, network, accounts) {
    // encapsulate everything with this `if` statement
    if (network == "production") {
        ...
    }
};

Por lo tanto, todo lo que está dentro de la ifdeclaración no se ejecuta cuando se ejecuta truffle test.

Y para mantener la opción de implementar mis contratos con Truffle, agregué esto en mi archivo de configuración de Truffle ( truffle.jso truffle-config.js):

    production: {
        host:       "localhost", // for example
        port:       7545,        // for example
        network_id: "*",         // for example
        gasPrice:   20000000000, // for example
        gas:        6721975      // for example
    }

Lo que me permite implementar mis contratos a través de cualquiera de las siguientes líneas de comando:

  • truffle deploy --network=production
  • truffle migrate --network=production

Antes de poder ejecutar cualquier prueba, uno tiene que definir el punto de partida, las condiciones de partida en el contrato inteligente. - Piensa en los valores de la variable en los contratos inteligentes. Estas condiciones están definidas por el proceso de implementación. Por lo tanto, generalmente uno ejecutaría primero la implementación antes de la prueba. Además, esto permite restablecer la cadena de bloques fácilmente después de cada prueba por separado.

Si no desea hacer esto, es posible que desee probar los scripts de trufa . Le permiten ejecutar cualquier script o prueba.

Gracias. No, me gustaría usarlo truffle testporque proporciona un buen informe. Me gustaría crear/implementar contratos yo mismo: diferentes contratos en cada prueba. Y ciertamente no los mismos para cada prueba. En algunas de mis pruebas, utilizo contratos de maqueta, con el propósito de probar un solo contrato de manera aislada (también conocido como unitest ). En el script de migración pasado a truffle deploy, me gustaría hacer "lo real", ya que aquí mi intención no es probar los contratos sino implementarlos.
Entonces es posible que desee utilizar banderas para la implementación: truffleframework.com/docs/advanced/configuration Si no se pasa ninguna bandera, simplemente no ejecuta ningún código de implementación. Luego, la prueba de trufa se ejecuta sin desplegarse. Si entrega --network "testnetName", podría ejecutar la implementación en la migración.
Así es exactamente como terminé resolviéndolo, por cierto (ejecutar solo si network == "production"). Gracias.
Aunque no los llamaría "banderas", de hecho, se pasan 3 parámetros al script: deployer, networky accounts.
Tengo el mismo requisito: antes de comenzar a desarrollar el código de interfaz para contratos ya implementados, ¡quiero realizar algunas pruebas para asegurarme de que funcionen correctamente! @josojo: ¿puede compartir exactamente cómo funcionaría 'sin banderas', por favor?
Esta respuesta realmente no aborda la pregunta, excepto quizás para explicar la lógica de los desarrolladores de Truffle, que es contraria a la práctica de prueba estándar (al obligar a que la configuración sea siempre la misma). Lo gracioso es que Truffle tampoco restablece la cadena de bloques después de cada prueba.

Para aquellos que se preguntan sobre una solución, aquí está la insinuada en los comentarios anteriores:

Primero, truffle-config.jsse ve algo como esto:

module.exports = {
  networks: {
    rinkeby: {
      host: "localhost", // Connect to geth on the specified
      port: 8545,
      from: "0x8f03ca885434522d695735a28d6a8a93b4390da9", // default address to use for any transaction Truffle makes during migrations
      network_id: 4,
      gas: 4612388 // Gas limit used for deploys
    }
};

Luego, en el script 2_deploy...:

if ( network === 'rinkeby' ) 
{ 
  return 
} 

Finalmente, en su script de prueba:

this.contract = await BlahContract.at('0x48B98faB029Cd2c77afA780Ab94c2d4e2f4879dA') 

Entonces corre:truffle test --network rinkeby

Obviamente, necesitará algo de éter Rinkeby y deberá desbloquear una cuenta, con algo como personal.unlockAccount(eth.coinbase, "yourPassword", 3000);desde la consola geth, pero tengo este método funcionando para mí. Hurra :)