Estoy tratando de escribir pruebas para contratos usando trufa; He abierto un tema aquí . El flujo de trabajo es el siguiente:
mkdir truffle_testing
truffle init
rm -r tests/* contracts/* build/*
A continuación, creo los siguientes archivos de contrato en el directorio contracts/ :
C.sol
contract C {
string words = "Bla bla bla";
uint256 lastVal;
function math(uint256 a, uint256 b) {
lastVal = a + b;
}
function getVal() constant returns (uint256) {
return lastVal;
}
function getWords() constant returns (string) {
return words;
}
}
y
Migraciones.sol
contract Migrations {
address public owner;
// A function with the signature `last_completed_migration()`, returning a uint, is required.
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _
}
function Migrations() {
owner = msg.sender;
}
// A function with the signature `setCompleted(uint)` is required.
function setCompleted(uint completed) restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
Luego creo un conjunto de pruebas en el directorio tests/ :
contract('C', function(accounts) {
it("Getting the words string from the contract", function() {
var c = C.deployed();
return c.getWords.call(accounts[0]).then(function(words) {
assert.equal(words, "Bla bla bla", "[E] The contract should have said \"Bla bla bla\"");
});
});
it(" 2 + 2 = 4 ", function(){
var c = C.deployed();
// Call method to initialize value (this method only returns the tx id and not the
// actual value)
c.math(2, 2, {from:accounts[0],gas:3000000}).then(function(tx_that_we_dont_need) {
return c.getVal.call().then(function(additionResult){
assert.equal(additionResult, 4, "[E] 2 + 2 = 4 even in eth. contracts.");
});
});
});
});
Después de escribir todos los archivos, lanzo testrpc :
testrpc:
EthereumJS TestRPC v2.1.0
Available Accounts
==================
...
luego construye el proyecto:
truffle compile --compile-all
truffle migrate
truffle test
Como era de esperar, todas las pruebas pasan pero también pasan si cambio el valor en la segunda prueba de 4 a cualquier otro valor entero.
¿Por qué?
Editar:
Agregué la devolución de llamada realizada a mis pruebas, pero no funciona (las pruebas aún se muestran como aprobadas cuando no deberían):
contract('C', function(accounts) {
it("Getting the words string from the contract", function() {
var c = C.deployed();
return c.getWords.call(accounts[0]).then(function(words) {
assert.equal(words, "Bla bla bla", "[E] The contract should have said \"Bla bla bla\"");
});
});
it(" 2 + 2 = 4 ", function(){
var c = C.deployed();
// Call method to initialize value (this method only returns the tx id and not the
// actual value)
c.math(2, 2, {from:accounts[0],gas:3000000}).then(function() {
return c.getVal.call().then(function(additionResult){
assert.equal(additionResult, 6, "[E] 2 + 2 = 4 even in eth. contracts.");
done();
}).done(null, function(error) {
done(error);
});
});
});
});
Editar #2:
He intentado ejecutar el siguiente código:
contract('C', function(accounts) {
it("Getting the words string from the contract", function() {
var c = C.deployed();
return c.getWords.call(accounts[0]).then(function(words) {
assert.equal(words, "Bla bla bla", "[E] The contract should have said \"Bla bla bla\"");
});
});
it(" 2 + 2 = 4 ", function(){
var c = C.deployed();
// Call method to initialize value (this method only returns the tx id and not the
// actual value)
c.math(2, 2, {from:accounts[0],gas:3000000}).then(function() {
return c.getVal.call().then(function(additionResult){
assert.equal(additionResult, 6, "[E] 2 + 2 = 4 even in eth. contracts.");
done();
}).done(null, function(error) {
done(error);
});
});
});
});
pero ahora aparece un error de tiempo de espera:
Contract: C
✓ Getting the words string from the contract (232ms)
1) 2 + 2 = 4
> No events were emitted
1 passing (5m)
1 failing
1) Contract: C 2 + 2 = 4 :
Error: timeout of 300000ms exceeded. Ensure the done() callback is being called in this test.
Creo que su problema está relacionado con cómo funciona mocha con código asíncrono : debe pasar una función done() a la función it y ejecutarla al final de su prueba, por lo que mocha espera hasta que se llame para realizar la prueba. Tiene ejemplos en el archivo de prueba metacoin.js que se envía con truffle 1 (no sé cómo se envía v.2).
Entonces, en tu prueba, debes hacer:
it("Getting the words string from the contract", function(done) {
var c = C.deployed();
return c.getWords.call(accounts[0]).then(function(words) {
assert.equal(words, "Bla bla bla", "[E] The contract should have said \"Bla bla bla\"");
})
.then(() => {done()})
.catch(done)
;
Sebí
Sebí
Sergeon
Sebí
Sergeon
Sergeon