テストデータどうしてますか?

3,285 views

Published on

Kansai.pm #14で発表した、「テストデータどうしてますか?」という資料です。

Published in: Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,285
On SlideShare
0
From Embeds
0
Number of Embeds
427
Actions
Shares
0
Downloads
4
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • テストデータどうしてますか?というタイトルで発表します、shiba_yu36です\n
  • まずは自己紹介から\n
  • 柴崎優季\nhatena, twitter, github\nはてなエンジニアバイト\n
  • perlとかjavascriptをよく使います\n
  • perlで作ったものとして\nbit.lyのapiラッパーであるWebService::Bitly、CSRFを自動的に防ぐMojoliciousプラグイン、あとは今回後で紹介するDBIx::DataFactory\n最近はCPANに上げる前にレビューをしてもらえるPrePANとかも手伝ってます\n
  • では本題です\n
  • \n
  • 色々方法はあると思う\nFixtureを使う、ORMとかを直接使ってデータを入れる、テストデータを生成するためのユーティリティ関数を用意してそれを使うなどの方法が考えられます\n1つずつ考えていきますね\n
  • \n
  • たとえばymlファイルにこんな感じでデータを書いておいて、\n
  • テストスクリプト内で読み込んでやると、テスト用のデータが生成されます\n
  • データと実際のテストが分離していて読みづらいことがある\n\n
  • もうfixtureとか使わずに直接テストスクリプト内でデータを入れたらいいんじゃないかって思いました\n
  • 次の方法なんですが、直接データを入れる方法についてです\n
  • DBIx::SampleをなんらかのORMとかとすると、こんな感じでcreateする\nこうしておくことでテストとデータの関係が見やすくなる\n
  • 結局さっき言ってた追加したデータでテストが落ちる\ncolumnが10個くらいあったらやばい、ちょっとしたテストを書きたいだけでも長くなる\n
  • \n
  • というわけで次の方法ですが、テストデータ生成用のユーティリティメソッドを作る方法です\n
  • 例えばこんな感じです。idとtitleのみのデータを入れることができるtableがあったとして、こういうふうにしておくと、データが指定してあればそれを入れる、そうでなければidに整数値をランダムで入れたり、titleに文字列をランダムで入れたりするようなメソッドができます。\n
  • 使い方はこんな感じですね。上の例だとランダムでデータが入るし、下だとtitleには指定したデータが入ります\nこうすれば、毎回書くの面倒じゃなくなるし、ランダムで入れる分データの競合も少なくなる、ちょっとしたテストを書きたいときでも手軽に書ける\n
  • \n
  • \n
  • \n
  • DBIx::DataFactoryというモジュールです\n
  • DBIx::DataFactoryというモジュールです\n
  • このようなschemaがあるとします。\nidが10桁の整数で、titleが20文字、bodyはtextです。\n
  • それでこのtableにデータを入れるためのメソッドをDBIx::DataFactoryを使って実装するとこのようになります\nインスタンスをdsnなど指定して作ります\n
  • method名、table名、自動的に生成したいcolumnを指定してメソッドを作成します。\n自動的に生成したいcolumnはデフォルトにあるtypeを指定してどんなデータを入れるか決めます\n今回だったらidにIntタイプで10桁、titleにStrタイプで20桁を指定しています\n
  • 作成したメソッドの使い方はこんな感じです。何も指定しないと、自動で生成する設定にしたcolumnに値が入ります。insertしたvaluesが帰ってきます\n
  • データを指定すると、指定したカラムには指定されたデータが、そうでないところには自動で生成するデータが入ります\n
  • 自動生成データとしてデフォルトで指定できるtypeは今のところ4種類です\nまた、プラガブルにしているので、自分でTypeを作成することも出来ます\n
  • もっと柔軟にデータを作れるように、coderefで作れるようにもしています。\n
  • こんな感じ\n
  • \n
  • YAPC::Asiaに行ったらモジュールが出来てたので、行くといいですね\n
  • \n
  • テストデータどうしてますか?

    1. 1. id:shiba_yu362011/11/26 Kansai.pm #14
    2. 2. • • shiba_yu36@hatena • @shiba_yu36 • shibayu36@github• •
    3. 3. # fixture.yml- name: entry1 data: id: 1 title: my policy- name: entry2 data: id: 2 title: please join
    4. 4. use Test::More;use Test::Fixture::DBI;construct_fixture( dbh => $dbh, fixture => /path/to/fixture.yaml,);
    5. 5. use Test::More;my $data = DBIx::Sample->create( id => 1, title => entry1,);my $data2 = DBIx::Sample->create( id => 2, title => entry2,);# add test ...
    6. 6. sub create_sample (;%) { my %args = @_; unless (defined $args{id}) { $args{id} = int(rand(1000000)); } my $sample = DBIx::Sample->create(id => $args{id}); unless ($args{title}) { $args{title} = String::Random->new->randregex([a-z]{40}); } $sample->title($args{title}); return $sample;}
    7. 7. use Test::More;my $data = create_sample;my $data2 = create_sample(title =>entry1);# add test ...
    8. 8. CREATE TABLE `sample` ( id int(10) unsigned NOT NULL, title varchar(20) NOT NULL, body text);
    9. 9. my $factory_maker = DBIx::DataFactory->new({ username => root, password => , dsn => dbi:mysql:dbname=sample,});
    10. 10. $factory_maker->create_factory_method( method => create_sample, table => sample, auto_inserted_columns => { id => { type => Int, size => 10, }, title => { type => Str, size => 20, }, },);
    11. 11. my $values = $factory_maker->create_sample;warn $values->{id};# +-----------+----------------------+------+# | id | title | body |# +-----------+----------------------+------+# | 452882908 | E54521Hpjkp9Wv1i9Rkb | NULL |# +-----------+----------------------+------+
    12. 12. my $values = $factory_maker->create_sample( title => title, body => body,);# +------------+-------+------+# | id | title | body |# +------------+-------+------+# | 3931487566 | title | body |# +------------+-------+------+
    13. 13. $factory_maker->create_factory_method( method => create_sample, table => sample, auto_inserted_columns => { id => sub { int rand(1000000000) }, title => { type => Str, size => 20, }, },);

    ×