Prueba unitaria Fecha Hora Valores

Tengo una función que hace uso de la hora actual ( now). El Contrato en su conjunto es un token de Crowdfunding y el costo de los tokens difiere según la fecha y la hora en que se compran.

¿Cómo se simulan diferentes momentos al probar un contrato inteligente? Por ejemplo, con respecto al código a continuación, me gustaría realizar pruebas unitarias para averiguar si el código para establecer el precio es correcto, pero no puedo cambiar el valor de now.

¿Sería una buena solución simplemente sustituir la nowpalabra clave por otra variable de prueba temporal, por ejemplo, now_simy luego cambiarla manualmente now_simdurante la simulación?

    if (now < (startTime + 1 days)) {
        currentPrice = safeDiv(safeMul(price, 80), 100);  // 20 % discount (x * 80 / 100)
    } 
    else if (now < (startTime + 2 days)) {
        currentPrice = safeDiv(safeMul(price, 90), 100);  // 10 % discount (x * 90 / 100)
    }
    else if (now < (startTime + 12 days)) {
        // 1 % reduction in the discounted rate from day 2 until day 12 (sliding scale per second)
        // 8640000 is 60 x 60 x 24 x 100 (100 for 1%) (60 x 60 x 24 for seconds per day)
        currentPrice = price - safeDiv(safeMul((startTime + 12 days) - now), price), 8640000);
    }
    else {
        currentPrice = price;
    }
Hay una manera de aumentar el tiempo con testrpc. Puede ayudar en este caso. Consulte evm_increaseTime: github.com/ethereumjs/testrpc
@RobHitchens SÍ: para las pruebas unitarias estándar basadas en Javascript en Truffle, evm_increaseTimesería la mejor opción para simular diferentes tiempos.
@RobHitchens, he buscado en toda la documentación de testrpc y truffle, pero no sé cómo usarlo evm_increaseTimedesde la consola de truffle. ¿Tal vez no puedes ayudar?
No lo he usado antes. Parece que la pregunta más general aquí es cómo acceder a cualquiera de los métodos TestRPC enumerados allí desde dentro del contexto de la trufa. No parece obvio.

Respuestas (2)

En general, sí, probablemente sea mejor establecer valores estáticos para todas las variables de prueba importantes.

En el contrato, nowes el block.timeStamp.

Este sello de tiempo es aproximado en la práctica, con variaciones de hasta quince minutos.

Consultaría el contrato o blockchain para obtener el tiempo que realmente se usó.

En situaciones similares, he tenido la prueba esperando un bloque minado con una marca de tiempo más allá de un tiempo que estoy esperando. Puedo ver cómo esto será un problema si tiene que esperar 12 días.

Podría ser bueno desglosar y parametrizar los hitos para que pueda probar con intervalos más pequeños, de modo que todo pueda pasar todas las pruebas en uno o dos minutos. Posiblemente no satisfactorio para una prueba "final", pero suficiente para las pruebas iniciales.

Espero eso ayude.

Si usa pyethereum para realizar pruebas, lo cual recomiendo encarecidamente, es encantador, puede modificar directamente la marca de tiempo del bloque simulado que está minando su transacción.

self.s = t.state()
self.s.block.timestamp = self.s.block.timestamp + 86400
self.s.mine(1)
some_val = your_contract.do_something(some_parameter)
self.assertEqual(some_val, whatever)

Vea un ejemplo de trabajo aquí (quizás un poco desactualizado): https://github.com/realitykeys/subjectivocracy/blob/master/contracts/test.py#L85

La trufa funciona mejor con testrpc. Intenté configurar pyethereum en Windows y me di por vencido después de un día más o menos. También pude encontrar alguna documentación sobre el código de solidez, ¿es solo compatible con serpiente?