We've been working on a few projects recently that have required a lot of XML to be generated. This XML is defined by a schema and as such must validate against it.
While the generated documents can be validated using external tools this was proving inconvienent and didn't integrate with the rest of the test-suites. Inspired by a recent post from Thoughtbot on validaing JSON schemas with RSpec I put together a custom RSpec matcher to provide the same functionality for XML.
Introducing RSpec-XSD
RSpec-XSD provides a single matcher to check that the document (or fragment) provided validates against the given schema.
To install the matcher just add the RSpec-XSD to your Gemfile.
group :test do
gem 'rspec-xsd'
end
Then require the gem in your spec_helper and include the matcher.
require 'rspec/xsd'
RSpec.configure do |config|
config.include RSpec::XSD
end
RSpec-XSD provides a single matcher (pass_validation
) to use in your specs, e.g.
describe MyXMLGenerator do
let(:schema) { '/path/to/schema.xsd' }
describe '.generate' do
context 'with valid input' do
let(:xml) { MyXMLGenerator.generate(valid_details) }
it 'validates' do
expect(xml).to pass_validation(schema)
end
end
context 'with invalid input' do
let(:xml) { MyXMLGenerator.generate(invalid_details) }
it 'does not validate' do
expect(xml).not_to pass_validation(schema)
end
end
end
end
Now when your specs run any validation issues will be raised in the failure message, e.g.
Failures:
1) MyXMLGenerator.generate with valid input validates
Failure/Error: expect(xml).to pass_validation(schema)
expected that XML would validate against schema.xsd
Element 'note': Missing child element(s). Expected is ( body ).
For further details or to submit a pull request or issue please refer to the repo on Github.