2

perl でサブルーチンの単体テストを書きたいと思っています。サブルーチンは複数のスレッドを使用してタスクを実行しています。そのため、最初にいくつかのスレッドを作成し、それらが参加するのを待ちます。

問題は、単体テストがマルチスレッド テストを実行できないサーバー上で実行されることです。そのため、何らかの方法でスレッドの動作を模擬する必要があります。基本的に、スレッドの作成および結合関数をオーバーライドして、スレッド化されないようにしたいと考えています。どうすればそれを実行してコードをテストできますか?

編集: サーバーは、次の理由により、スレッド化されたコードの実行に失敗します。

Devel::Cover はまだスレッドで動作しません

4

1 に答える 1

5

更新:編集された質問で説明されているように、この回答はOPの問題を解決しませんが、誰かにとって役立つかもしれません。

Perl スレッドはインタプリタのエミュレーションであり、オペレーティング システムの機能ではありません。したがって、それらはどのプラットフォームでも動作するはずです。テスト サーバーがスレッドをサポートしていない場合は、次のいずれかの理由が考えられます。

  1. お使いの Perl のバージョンは非常に古いです。
  2. Perl は、スレッド サポートなしでコンパイルされました。
  3. テスト フレームワークは、スレッド化されたコードを念頭に置いて作成されていません。

最初の 2 つは、環境を更新することで簡単に修正できます。ただし、あなたの問題は3番目の問題だと思います。

スレッドの動作を嘲笑してこれを解決するべきではないと思います。これにより、元のコードが変更されすぎて、有効なテストになりません。とにかくかなりの量の作業になるので、その労力をスレッド化されたテストを機能させることに向けてみませんか?

正確な問題はコードによって異なりますが、おそらく問題は、サブルーチンがスレッドを開始してから戻り、スレッドがまだ実行されていることです。次に、テスト フレームワークはサブルーチンを何度も実行し、多数の同時スレッドを蓄積します。

その場合、必要なのは、テストしているサブルーチンを呼び出し、スレッドが完了するまでブロックするラッパー サブルーチンだけです。これはかなり単純なはずです。を見て、threads->list()実行中のスレッドを検出する方法を確認してください。ラッパーサブルーチンを終了する前に、問題のスレッドが実行されなくなるまで待機するループを作成するだけです。

ラッパーサブを示す簡単な完全な例を次に示します。

#!usr/bin/perl
use strict;
use warnings;
use threads;

sub sub_to_test {

    threads->create(sub { sleep 5; print("Thread done\n"); threads->detach() });
    return "Sub done\n";
}

sub wrapper {
    #Get a count of the running threads.
    my $original_running_threads = threads->list(threads::running);

    my @results = sub_to_test(@_);

    #block until the number of running threads is the same as when we started.
    sleep 1 while (threads->list(threads::running) > $original_running_threads);

    return @results;
}

print wrapper;
于 2013-01-16T11:51:03.503 に答える