You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

junit_spec.rb 13 kB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. # frozen_string_literal: true
  2. require 'spec_helper'
  3. require 'cucumber/formatter/spec_helper'
  4. require 'cucumber/formatter/junit'
  5. require 'nokogiri'
  6. module Cucumber
  7. module Formatter
  8. class TestDoubleJunitFormatter < ::Cucumber::Formatter::Junit
  9. attr_reader :written_files
  10. def initialize(config)
  11. super
  12. config.on_event :test_step_started, &method(:on_test_step_started)
  13. end
  14. def on_test_step_started(_event)
  15. Interceptor::Pipe.unwrap! :stdout
  16. @fake_io = $stdout = StringIO.new
  17. $stdout.sync = true
  18. @interceptedout = Interceptor::Pipe.wrap(:stdout)
  19. end
  20. def on_test_step_finished(event)
  21. super
  22. $stdout = STDOUT
  23. @fake_io.close
  24. end
  25. def write_file(feature_filename, data)
  26. @written_files ||= {}
  27. @written_files[feature_filename] = data
  28. end
  29. end
  30. describe Junit do
  31. extend SpecHelperDsl
  32. include SpecHelper
  33. context 'With --junit,fileattribute=true option' do
  34. before(:each) do
  35. allow(File).to receive(:directory?) { true }
  36. @formatter = TestDoubleJunitFormatter.new(
  37. actual_runtime.configuration.with_options(
  38. out_stream: '',
  39. formats: [['junit', { 'fileattribute' => 'true' }]]
  40. )
  41. )
  42. end
  43. describe 'includes the file' do
  44. before(:each) do
  45. run_defined_feature
  46. @doc = Nokogiri.XML(@formatter.written_files.values.first)
  47. end
  48. define_steps do
  49. Given(/a passing scenario/) do
  50. Kernel.puts 'foo'
  51. end
  52. end
  53. define_feature <<-FEATURE
  54. Feature: One passing feature
  55. Scenario: Passing
  56. Given a passing scenario
  57. FEATURE
  58. it 'will contain the file attribute' do
  59. expect(@doc.xpath('//testsuite/testcase/@file').size).to equal 1
  60. expect(@doc.xpath('//testsuite/testcase/@file').first.value).to eq('spec.feature')
  61. end
  62. end
  63. end
  64. context 'With --junit,fileattribute=different option' do
  65. before(:each) do
  66. allow(File).to receive(:directory?) { true }
  67. @formatter = TestDoubleJunitFormatter.new(
  68. actual_runtime.configuration.with_options(
  69. out_stream: '',
  70. formats: [['junit', { 'fileattribute' => 'different' }]]
  71. )
  72. )
  73. end
  74. describe 'includes the file' do
  75. before(:each) do
  76. run_defined_feature
  77. @doc = Nokogiri.XML(@formatter.written_files.values.first)
  78. end
  79. define_steps do
  80. Given(/a passing scenario/) do
  81. Kernel.puts 'foo'
  82. end
  83. end
  84. define_feature <<-FEATURE
  85. Feature: One passing feature
  86. Scenario: Passing
  87. Given a passing scenario
  88. FEATURE
  89. it 'will not contain the file attribute' do
  90. expect(@doc.xpath('//testsuite/testcase/@file').size).to equal 0
  91. end
  92. end
  93. end
  94. context 'With --junit no fileattribute option' do
  95. before(:each) do
  96. allow(File).to receive(:directory?) { true }
  97. @formatter = TestDoubleJunitFormatter.new(actual_runtime.configuration.with_options(out_stream: ''))
  98. end
  99. describe 'includes the file' do
  100. before(:each) do
  101. run_defined_feature
  102. @doc = Nokogiri.XML(@formatter.written_files.values.first)
  103. end
  104. define_steps do
  105. Given(/a passing scenario/) do
  106. Kernel.puts 'foo'
  107. end
  108. end
  109. define_feature <<-FEATURE
  110. Feature: One passing scenario
  111. Scenario: Passing
  112. Given a passing scenario
  113. FEATURE
  114. it 'will not contain the file attribute' do
  115. expect(@doc.xpath('//testsuite/testcase/@file').size).to equal 0
  116. end
  117. end
  118. end
  119. context 'With no options' do
  120. before(:each) do
  121. allow(File).to receive(:directory?) { true }
  122. @formatter = TestDoubleJunitFormatter.new(actual_runtime.configuration.with_options(out_stream: ''))
  123. end
  124. describe 'is able to strip control chars from cdata' do
  125. before(:each) do
  126. run_defined_feature
  127. @doc = Nokogiri.XML(@formatter.written_files.values.first)
  128. end
  129. define_steps do
  130. Given(/a passing ctrl scenario/) do
  131. Kernel.puts "boo\b\cx\e\a\f boo "
  132. end
  133. end
  134. define_feature <<-FEATURE
  135. Feature: One passing scenario, one failing scenario
  136. Scenario: Passing
  137. Given a passing ctrl scenario
  138. FEATURE
  139. it { expect(@doc.xpath('//testsuite/testcase/system-out').first.content).to match(/\s+boo boo\s+/) }
  140. end
  141. describe 'a feature with no name' do
  142. define_feature <<-FEATURE
  143. Feature:
  144. Scenario: Passing
  145. Given a passing scenario
  146. FEATURE
  147. it 'raises an exception' do
  148. expect { run_defined_feature }.to raise_error(Junit::UnNamedFeatureError)
  149. end
  150. end
  151. describe 'given a single feature' do
  152. before(:each) do
  153. run_defined_feature
  154. @doc = Nokogiri.XML(@formatter.written_files.values.first)
  155. end
  156. describe 'with a single scenario' do
  157. define_feature <<-FEATURE
  158. Feature: One passing scenario, one failing scenario
  159. Scenario: Passing
  160. Given a passing scenario
  161. FEATURE
  162. it { expect(@doc.to_s).to match(/One passing scenario, one failing scenario/) }
  163. it 'has not a root system-out node' do
  164. expect(@doc.xpath('//testsuite/system-out').size).to eq 0
  165. end
  166. it 'has not a root system-err node' do
  167. expect(@doc.xpath('//testsuite/system-err').size).to eq 0
  168. end
  169. it 'has a system-out node under <testcase/>' do
  170. expect(@doc.xpath('//testcase/system-out').size).to eq 1
  171. end
  172. it 'has a system-err node under <testcase/>' do
  173. expect(@doc.xpath('//testcase/system-err').size).to eq 1
  174. end
  175. end
  176. describe 'with a scenario in a subdirectory' do
  177. define_feature %(
  178. Feature: One passing scenario, one failing scenario
  179. Scenario: Passing
  180. Given a passing scenario
  181. ), File.join('features', 'some', 'path', 'spec.feature')
  182. it 'writes the filename with absolute path' do
  183. expect(@formatter.written_files.keys.first).to eq File.absolute_path('TEST-features-some-path-spec.xml')
  184. end
  185. end
  186. describe 'with a scenario outline table' do
  187. define_steps do
  188. Given(/.*/) {}
  189. end
  190. define_feature <<-FEATURE
  191. Feature: Eat things when hungry
  192. Scenario Outline: Eat things
  193. Given <Things>
  194. And stuff:
  195. | foo |
  196. | bar |
  197. Examples: Good
  198. | Things |
  199. | Cucumber |
  200. | Whisky |
  201. Examples: Evil
  202. | Things |
  203. | Big Mac |
  204. FEATURE
  205. it { expect(@doc.to_s).to match(/Eat things when hungry/) }
  206. it { expect(@doc.to_s).to match(/Cucumber/) }
  207. it { expect(@doc.to_s).to match(/Whisky/) }
  208. it { expect(@doc.to_s).to match(/Big Mac/) }
  209. it { expect(@doc.to_s).not_to match(/Things/) }
  210. it { expect(@doc.to_s).not_to match(/Good|Evil/) }
  211. it { expect(@doc.to_s).not_to match(/type="skipped"/) }
  212. end
  213. describe 'scenario with skipped test in junit report' do
  214. define_feature <<-FEATURE
  215. Feature: junit report with skipped test
  216. Scenario Outline: skip a test and junit report of the same
  217. Given a <skip> scenario
  218. Examples:
  219. | skip |
  220. | undefined |
  221. | still undefined |
  222. FEATURE
  223. it { expect(@doc.to_s).to match(/skipped="2"/) }
  224. end
  225. describe 'with a regular data table scenario' do
  226. define_steps do
  227. Given(/the following items on a shortlist/) { |table| }
  228. When(/I go.*/) {}
  229. Then(/I should have visited at least/) { |table| }
  230. end
  231. define_feature <<-FEATURE
  232. Feature: Shortlist
  233. Scenario: Procure items
  234. Given the following items on a shortlist:
  235. | item |
  236. | milk |
  237. | cookies |
  238. When I get some..
  239. Then I'll eat 'em
  240. FEATURE
  241. # these type of tables shouldn't crash (or generate test cases)
  242. it { expect(@doc.to_s).not_to match(/milk/) }
  243. it { expect(@doc.to_s).not_to match(/cookies/) }
  244. end
  245. context 'with failing hooks' do
  246. describe 'with a failing before hook' do
  247. define_steps do
  248. Before do
  249. raise 'Before hook failed'
  250. end
  251. Given(/a passing step/) do
  252. end
  253. end
  254. define_feature <<-FEATURE
  255. Feature: One passing scenario
  256. Scenario: Passing
  257. Given a passing step
  258. FEATURE
  259. it { expect(@doc.to_s).to match(/Before hook at spec\/cucumber\/formatter\/junit_spec.rb:(\d+)/) }
  260. end
  261. describe 'with a failing after hook' do
  262. define_steps do
  263. After do
  264. raise 'After hook failed'
  265. end
  266. Given(/a passing step/) do
  267. end
  268. end
  269. define_feature <<-FEATURE
  270. Feature: One passing scenario
  271. Scenario: Passing
  272. Given a passing step
  273. FEATURE
  274. it { expect(@doc.to_s).to match(/After hook at spec\/cucumber\/formatter\/junit_spec.rb:(\d+)/) }
  275. end
  276. describe 'with a failing after step hook' do
  277. define_steps do
  278. AfterStep do
  279. raise 'AfterStep hook failed'
  280. end
  281. Given(/a passing step/) do
  282. end
  283. end
  284. define_feature <<-FEATURE
  285. Feature: One passing scenario
  286. Scenario: Passing
  287. Given a passing step
  288. FEATURE
  289. it { expect(@doc.to_s).to match(/AfterStep hook at spec\/cucumber\/formatter\/junit_spec.rb:(\d+)/) }
  290. end
  291. describe 'with a failing around hook' do
  292. define_steps do
  293. Around do |_scenario, block|
  294. block.call
  295. raise 'Around hook failed'
  296. end
  297. Given(/a passing step/) do
  298. end
  299. end
  300. define_feature <<-FEATURE
  301. Feature: One passing scenario
  302. Scenario: Passing
  303. Given a passing step
  304. FEATURE
  305. it { expect(@doc.to_s).to match(/Around hook\n\nMessage:/) }
  306. end
  307. end
  308. end
  309. end
  310. context 'In --expand mode' do
  311. let(:runtime) { Runtime.new(expand: true) }
  312. before(:each) do
  313. allow(File).to receive(:directory?) { true }
  314. @formatter = TestDoubleJunitFormatter.new(actual_runtime.configuration.with_options(out_stream: '', expand: true))
  315. end
  316. describe 'given a single feature' do
  317. before(:each) do
  318. run_defined_feature
  319. @doc = Nokogiri.XML(@formatter.written_files.values.first)
  320. end
  321. describe 'with a scenario outline table' do
  322. define_steps do
  323. Given(/.*/) {}
  324. end
  325. define_feature <<-FEATURE
  326. Feature: Eat things when hungry
  327. Scenario Outline: Eat things
  328. Given <Things>
  329. And stuff:
  330. | foo |
  331. | bar |
  332. Examples: Good
  333. | Things |
  334. | Cucumber |
  335. | Whisky |
  336. Examples: Evil
  337. | Things |
  338. | Big Mac |
  339. FEATURE
  340. it { expect(@doc.to_s).to match(/Eat things when hungry/) }
  341. it { expect(@doc.to_s).to match(/Cucumber/) }
  342. it { expect(@doc.to_s).to match(/Whisky/) }
  343. it { expect(@doc.to_s).to match(/Big Mac/) }
  344. it { expect(@doc.to_s).not_to match(/Things/) }
  345. it { expect(@doc.to_s).not_to match(/Good|Evil/) }
  346. it { expect(@doc.to_s).not_to match(/type="skipped"/) }
  347. end
  348. end
  349. end
  350. end
  351. end
  352. end

No Description

Contributors (1)