25
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RubyでAtcoderからテストを自動生成するライブラリを作りました

Last updated at Posted at 2020-02-10

Atcoderのコンテストにチマチマでているのですが、最近Rustでテスト生成や提出ができるCLIツールを作っている方を見かけました。
https://github.com/tanakh/cargo-atcoder

丁度コンテスト時に入出力例をいちいち試すのが面倒だと感じていたので、Rubyでもテストを自動生成するGemをつくってみました。

使い方

インストール

gem install green_dayなりでインストールしてください。

ログイン

bundle exec green_day login
でユーザー名とパスワードを要求されるので入力してください。
Atcoderからのset-cookieの中身をcookie-storeというファイルに保存します。セッションを消したかったらこのファイルを削除してください。
セッションがないと開催中のコンテストにアクセスすることができません。

作業用ディレクトリ及びテストの作成

このコマンドでコンテスト用のディレクトリ及びテストを生成できます。

bundle exec green_day new <contest-name>

例えばabc150を対象にしたいときは下のようになります。
bundle exec green_day new abc150
こうするとこんな感じのディレクトリ構成になります。

 abc150
 ├── A.rb
 ├── B.rb
 ├── C.rb
 ├── D.rb
 ├── E.rb
 ├── F.rb
 └── spec
     ├── A_spec.rb
     ├── B_spec.rb
     ├── C_spec.rb
     ├── D_spec.rb
     ├── E_spec.rb
     └── F_spec.rb

自動生成されるテストは例えばabc150のA問題ならこんな感じになります。

require 'rspec'

RSpec.describe 'test' do
 it 'test with "2 900\\n"' do
   io = IO.popen("ruby abc150/A.rb", "w+")
   io.puts("2 900\\n")
   io.close_write
   expect(io.readlines.join).to eq("Yes\\n")
 end

 it 'test with "1 501\\n"' do
   io = IO.popen("ruby abc150/A.rb", "w+")
   io.puts("1 501\\n")
   io.close_write
   expect(io.readlines.join).to eq("No\\n")
 end

 it 'test with "4 2000\\n"' do
   io = IO.popen("ruby abc150/A.rb", "w+")
   io.puts("4 2000\\n")
   io.close_write
   expect(io.readlines.join).to eq("Yes\\n")
 end

end

後はabc150/A.rbに提出用のコードをそのまま書けばOKです。

n, m = gets.split.map(&:to_i)
 
if 500 * n >= m
  puts "Yes"
else
  puts "No"
end

いつものようにrspecでテストすることができます。

> rspec abc150/spec/A_spec.rb
...

Finished in 0.15933 seconds (files took 0.08655 seconds to load)
3 examples, 0 failures

テスト名に入力例をそのまま入れているのでテスト結果はそれをみて判断してください。

  3) test test with "4 2000\n"
     Failure/Error: expect(io.gets).to eq("Yes\n")
     
       expected: "Yes\n"
            got: "No\n"
     
       (compared using ==)
     
       Diff:
       @@ -1,2 +1,2 @@
       -Yes
       +No
       

後書きとか

一応CIではRuby 2.7.0とAtcoder用にRuby2.3.3でテストしています。
(ローカルでは2.3系は入れるのが面倒だったので未確認です)
入出力例のスクレイピングは全コンテスト試したわけではないので、未対応のケースがあるかもしれません。もし見つけたら教えてくれると嬉しいです。
提出まわりはつくっていないのですが気が向いたら作ります。

2020/02/11追記

spec.filesを消したままなのを忘れてリリースしてました。
すいませんでした!!!!!!!!
修正しました!!!!!!!

2020/02/18追記

複数行の回答の出力に対応しました

25
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?