Ich schreibe gerne zwei oder mehr Testmethoden, die auf parallelen Threads ausgeführt werden, und jede von ihnen ruft das zu testende Objekt auf. Bisher habe ich Sleep()-Aufrufe verwendet, um die Reihenfolge der Aufrufe in den verschiedenen Threads zu koordinieren, aber das ist nicht wirklich zuverlässig. Es ist auch viel langsamer, weil man lange genug schlafen muss, damit das Timing normalerweise funktioniert.
Ich fand die Multithreading TC Java-Bibliothek von der gleichen Gruppe, die FindBugs geschrieben hat. Damit können Sie die Reihenfolge der Ereignisse festlegen, ohne Sleep() zu verwenden, und es ist zuverlässig. Ich habe es noch nicht ausprobiert.
Die größte Einschränkung dieses Ansatzes ist, dass Sie nur die Szenarien testen können, von denen Sie vermuten, dass sie Probleme verursachen werden. Wie andere bereits gesagt haben, müssen Sie Ihren Multithreading-Code wirklich in eine kleine Anzahl einfacher Klassen isolieren, damit Sie überhaupt die Möglichkeit haben, ihn gründlich zu testen.
Nachdem Sie die Szenarien, von denen Sie erwarten, dass sie Probleme verursachen, sorgfältig getestet haben, ist ein unwissenschaftlicher Test, bei dem eine Reihe von gleichzeitigen Anfragen an die Klasse gestellt werden, ein guter Weg, um nach unerwarteten Problemen zu suchen.
Aktualisierung: Ich habe ein wenig mit der Multithreaded TC Java-Bibliothek gespielt, und es funktioniert gut. Ich habe auch einige ihrer Funktionen in eine .NET-Version portiert, die ich TickingTest .
2 Stimmen
Ich hatte vor, eine Frage zu genau diesem Thema zu stellen. Obwohl Will im Folgenden viele gute Punkte anführt, denke ich, dass wir es besser machen können. Ich stimme zu, dass es keinen einzigen "Ansatz" gibt, um das Problem sauber zu lösen. Aber "so gut wie möglich zu testen" setzt die Messlatte sehr niedrig an. Ich werde mit meinen Ergebnissen zurückkommen.
0 Stimmen
In Java: Das Paket java.util.concurrent enthält einige schlecht bekannte Klassen, die helfen können, deterministische JUnit-Tests zu schreiben. Werfen Sie einen Blick auf - CountDownLatch - Semaphor - Austauscher
0 Stimmen
Können Sie bitte einen Link zu Ihrer vorherigen Frage zu Unit-Tests angeben?
0 Stimmen
@Andrew Grimm: stackoverflow.com/questions/11060/
0 Stimmen
stackoverflow.com/questions/4418373/
20 Stimmen
Ich denke, es ist wichtig, darauf hinzuweisen, dass diese Frage 8 Jahre alt ist und die Anwendungsbibliotheken in der Zwischenzeit einen weiten Weg zurückgelegt haben. In der "modernen Ära" (2016) kommt Multi-Thread-Entwicklung vor allem in eingebetteten Systemen vor. Wenn Sie jedoch an einer Desktop- oder Telefonanwendung arbeiten, sollten Sie sich zunächst über die Alternativen informieren. Anwendungsumgebungen wie .NET enthalten inzwischen Tools, die wahrscheinlich 90 % der üblichen Multi-Threading-Szenarien verwalten oder stark vereinfachen. (asnync/await, PLinq, IObservable, die TPL...). Multithreading-Code ist schwierig. Wenn man das Rad nicht neu erfindet, muss man es auch nicht neu testen.
0 Stimmen
Dies mag eine unpopuläre Idee sein, aber wenn Sie Ihren Code in Rust schreiben, ohne
unsafe
Blöcken kann der Compiler tatsächlich rennfreie Threadsicherheit garantieren. Für mich ist dies ein noch wichtigeres Merkmal von Rust als die Speichersicherheit, die normalerweise erwähnt wird.