Unit Testing Date Time-Werte

Ich habe eine Funktion, die die aktuelle Uhrzeit verwendet ( now). Der Vertrag als Ganzes ist ein Crowdfunding-Token und die Kosten für Token variieren je nach Datum und Uhrzeit des Kaufs der Token.

Wie simuliert man verschiedene Zeiten beim Testen eines Smart Contracts? In Bezug auf den folgenden Code möchte ich beispielsweise Komponententests durchführen, um herauszufinden, ob der Code zum Festlegen des Preises korrekt ist, aber ich kann den Wert von nicht ändern now.

Wäre es eine gute Lösung, das nowSchlüsselwort einfach durch eine andere temporäre Testvariable zu ersetzen, sagen wir, und es dann während der Simulation now_simmanuell zu ändern ?now_sim

    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;
    }
Es gibt eine Möglichkeit, die Zeit mit testrpc zu erhöhen. Kann in diesem Fall helfen. Sehen Sie sich evm_increaseTime an: github.com/ethereumjs/testrpc
@RobHitchens JA: Für Standard-Javascript-basierte Komponententests in Truffle evm_increaseTimewäre dies die beste Option, um verschiedene Zeiten zu simulieren.
@RobHitchens, ich habe die gesamte Testrpc- und Truffle-Dokumentation durchsucht, aber ich kann nicht herausfinden, wie man sie evm_increaseTimevon der Truffle-Konsole aus verwendet. Kannst du vielleicht nicht helfen??
Habe es noch nie benutzt. Die allgemeinere Frage scheint hier zu sein, wie auf eine der dort aufgeführten TestRPC-Methoden aus dem Truffle-Kontext zugegriffen werden kann. Scheint nicht offensichtlich zu sein.

Antworten (2)

Im Allgemeinen ja, wahrscheinlich besser, statische Werte für alle wichtigen Testvariablen festzulegen.

Im Vertrag nowsteht die block.timeStamp.

Dieser Zeitstempel ist in der Praxis ungefähr , mit Abweichungen von bis zu fünfzehn Minuten.

Ich würde den Vertrag oder die Blockchain abfragen, um die tatsächlich verbrauchte Zeit zu erfahren.

In ähnlichen Situationen habe ich den Test auf einen abgebauten Block mit einem Zeitstempel warten lassen, der hinter einer Zeit liegt, auf die ich warte. Ich kann mir vorstellen, dass dies ein Problem sein wird, wenn Sie 12 Tage warten müssen.

Es könnte gut sein, die Meilensteine ​​aufzuschlüsseln und zu parametrisieren, damit Sie mit kleineren Intervallen testen können, sodass das Ganze alle Tests in ein oder zwei Minuten bestehen kann. Für einen "letzten" Test möglicherweise nicht ausreichend, aber für erste Tests ausreichend.

Ich hoffe es hilft.

Wenn Sie Pyethereum zum Testen verwenden – was ich sehr empfehle, ist es sehr schön – können Sie den Zeitstempel des simulierten Blocks, der Ihre Transaktion abbaut, direkt ändern.

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)

Sehen Sie hier ein funktionierendes Beispiel (vielleicht etwas veraltet): https://github.com/realitykeys/subjectivocracy/blob/master/contracts/test.py#L85

Truffle funktioniert am besten mit testrpc. Ich habe versucht, Pyethereum unter Windows einzurichten, und nach etwa einem Tag aufgegeben. Ich konnte auch Dokumentationen zum Solidity-Code finden, ist er nur mit Serpent kompatibel?