画面仕様書等、Markdownで整理していたものからRSpecを書き直すのが意外と手間と思うことがあったのでMarkdownで書いたものをRSpec形式のテキストに変換するGemを作りました。
使い方
使い方は、
$ gem install markdown_to_rspec # CLI $ markdown_to_rspec -f `MARKDOWN_FILE_PATH` #=> return A string in RSpec format $ markdown_to_rspec -t `MARKDOWN__TEXT` #=> return A string in RSpec format
上記ようにgemをinstall後に引数に以下の値を渡すことでRSpec形式の文字列に変換します。
例えばこのような画面仕様書的なマークダウンを変換すると、
# Details. A screen to check something ref: https://example/com/tickets/1 ## Initial Display. ### When a record exists. * The title must be displayed. * The text must be displayed. ### When the record does not exist. * The title should not be displayed. * The text should not be displayed. ### Other cases. * 500 pages to be displayed. # Index. A screen to check something ## Initial Display. * The items must be displayed.
以下のようなRSpec形式の文字列を取得出来ます✨
RSpec.describe 'Details.' do # A screen to check something # ref: https://example/com/tickets/1 describe 'Initial Display.' do context 'When a record exists.' do it 'The title must be displayed.' do end it 'The text must be displayed.' do end end context 'When the record does not exist.' do it 'The title should not be displayed.' do end it 'The text should not be displayed.' do end end context 'Other cases.' do it '500 pages to be displayed.' do end end end end RSpec.describe 'Index.' do # A screen to check something describe 'Initial Display.' do it 'The items must be displayed.' do end end end
※インデントの数やMarkdownの#
のどのレベルをdescribe
or context
にする等は一旦固定値になっているので調整出来ません🙏💦
個人的な技術Topic
作った上で個人的な技術Topicをちょっと書いときます。
RDoc::Markdown
を使ってマークダウンから中間オブジェクトを生成
MarkdownからRSpecに変換する際になんかしらの中間的なオブジェクトを生成する必要がありそうだなぁと思い、 なんかいい感じのgemを探していたのですが見つからず。。。
そういればRDocってMarkdown形式でかけるなと思い標準ライブラリを探していたら、
RDoc::Markdown
がまさにな感じだったのでそれを使うことにしました。
下記のような感じでMarkdown形式の文字列をRDoc::Markdown.parse
に渡してあげると、
RDoc::Markup::Document
というMarkdownのアイテムの関係性を保持した中間のオブジェクトを返却してくれます。
require 'rdoc/markdown' markdown = <<~MARKDOWN # title ## subtitle * item 1 * item 2 MARKDOWN RDoc::Markdown.parse(markdown) #=> #<RDoc::Markup::Document:0x00007f92f0b2e398 @parts=[#<struct RDoc::Markup::Heading level=1, text="title">, #<struct RDoc::Markup::Heading level=2, text="subtitle">, #<RDoc::Markup::List:0x00007f92f11dd928 @type=:BULLET, @items=[#<RDoc::Markup::ListItem:0x00007f92f0b65f78 @label=nil, @parts=[#<RDoc::Markup::Paragraph:0x00007f92f11e3828 @parts=["item 1"]>]>, #<RDoc::Markup::ListItem:0x00007f92f11e8fa8 @label=nil, @parts=[#<RDoc::Markup::Paragraph:0x00007f92f0b54b38 @parts=["item 2"]>]>]>], @file=nil, @omit_headings_from_table_of_contents_below=nil>
このオブジェクトをRSpecに変換するコードを今回は実装しています。
この辺のRDoc::Markup::Formatter
を継承したクラスを作ったほうがいい感じに出来たのかも・・・?
※今回は使い方を学習するのが結構難しそうで自前で実装してしまった。。。
OptionParser
を使ってCLIのインタフェースを定義
CLI部分のインタフェース部分を標準ライブラリのOptionParser
を使って実装してます。
OptionParser
を使うと下記のような感じで実行時に渡されたオプションに対して何を実行するのかを定義出来ます。
option.on
で指定されたオプションと実行する処理を紐付けして、option.parse!(ARGV)
で、
実行時引数を元に実行する処理を判定して引数をよしなに渡してくれるようです✨(便利)
require 'optparse' require 'markdown_to_rspec/rake_tasks' option = OptionParser.new option.on('-f', '--file FILE_PATH', 'Set the target Markdown file path.') do |v| Rake::Task['markdown_to_rspec:to_rspec_from_file'].execute(file_path: v) end option.on('-v', '--version', 'Show gem version.') do Rake::Task['markdown_to_rspec:version'].execute end option.parse!(ARGV)
上記のような設定だと以下のような動きになります。
-f
、--format
の時に引数で渡された値を元にRake::Task['markdown_to_rspec:to_rspec_from_file']
を実行 例)$ markdown_to_rspec -f sample.md
-v
、--version
の時にRake::Task['markdown_to_rspec:version']
を実行 例)$ markdown_to_rspec -v
あとは--help
も自動で実装してくれます✨
$ markdown_to_rspec -h Usage: markdown_to_rspec [options] -f, --file FILE_PATH Set the target Markdown file path. -v, --version Show gem version.
おわりに
マークダウン形式で書かれた画面仕様書からRSpecのE2Eテスト等を作るときに、 抜け漏れ等を防げて便利な気がするので、せっかく作ったので使っていこうと思います💪
色々調べるとRubyの標準ライブラリ、便利ですね✨