Using node attributes in Kitchen ServerSpec tests

Hi folks,
I’m new to Test Kitchen and trying to make sense of it all. I’m also new to
TDD (and programming in general) so the weird pseudocodey language used by
RSpec messes with my head because I’m expecting code and it reads more like
English.
Anyway.
Right now I’d like to see if I can use one of my nodes’ attributes to run
tests.
Specifically, I have something like this:

attributes/default.rb:
case node[‘platform’]
when 'centos’
default[‘myrecipe’][‘packages’] = %w(package1 package2)
when 'ubuntu’
default[‘myrecipe’][‘packages’] = %w(package3 package4)
end

recipes/default.rb:
node[‘myrecipe’][‘packages’].each do |pkg|
package pkg
end

Now, in my tests, what I’d like is to do something like:

node[‘myrecipe’][‘packages’].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven’t tested it because I’m done for
today but I looked at other people’s code on GitHub and found similar
things, so I imagine that it works):
case os[‘family’]
when 'centos’
packages = %w(package1 package2)
when 'ubuntu’
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that’s nice, but it requires maintaining on top of
the list of attributes in the attributes/default.rb file, hence my
wondering whether there is a way for Kitchen to grab those values off the
cookbook. Because that would be more efficient.

Is that possible? Or am I doomed?

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like Chef itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do what you want.

In any case, ask yourself if you really need to test that the packages are installed. If the package provides a service, you can make ServerSpec verify that the service is running (it’s got a resource for that), or that a certain port has a listening TCP socket or something else. Think about the actual functionality you want to assert instead of the method used to put it there.

If you still see value in testing that specific packages were installed, then I guess you’ll have to be explicit in your tests as well as on the code.


Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (fabien.delpierre@gmail.com) wrote:

Hi folks,
I’m new to Test Kitchen and trying to make sense of it all. I’m also new to TDD (and programming in general) so the weird pseudocodey language used by RSpec messes with my head because I’m expecting code and it reads more like English.
Anyway.
Right now I’d like to see if I can use one of my nodes’ attributes to run tests.
Specifically, I have something like this:

attributes/default.rb:
case node[‘platform’]
when 'centos’
default[‘myrecipe’][‘packages’] = %w(package1 package2)
when 'ubuntu’
default[‘myrecipe’][‘packages’] = %w(package3 package4)
end

recipes/default.rb:
node[‘myrecipe’][‘packages’].each do |pkg|
package pkg
end

Now, in my tests, what I’d like is to do something like:

node[‘myrecipe’][‘packages’].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven’t tested it because I’m done for today but I looked at other people’s code on GitHub and found similar things, so I imagine that it works):
case os[‘family’]
when 'centos’
packages = %w(package1 package2)
when 'ubuntu’
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that’s nice, but it requires maintaining on top of the list of attributes in the attributes/default.rb file, hence my wondering whether there is a way for Kitchen to grab those values off the cookbook. Because that would be more efficient.

Is that possible? Or am I doomed?

Fabien-

I implemented exactly what you’re looking for by following the test fixture cookbook approach discussed in this blog article [1]. Using this, I can reference the node attributes within my ServerSpec tests.

  • John

[1] http://jakshi.com/blog/2014/05/12/accessing-chef-attributes-in-serverspec-tests/

From: Cassiano Leal
Reply-To: "chef@lists.opscode.commailto:chef@lists.opscode.com"
Date: Tuesday, May 12, 2015 at 7:03 PM
To: Fabien Delpierre, "chef@lists.opscode.commailto:chef@lists.opscode.com"
Subject: [chef] Re: Using node attributes in Kitchen ServerSpec tests

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like Chef itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do what you want.

In any case, ask yourself if you really need to test that the packages are installed. If the package provides a service, you can make ServerSpec verify that the service is running (it’s got a resource for that), or that a certain port has a listening TCP socket or something else. Think about the actual functionality you want to assert instead of the method used to put it there.

If you still see value in testing that specific packages were installed, then I guess you’ll have to be explicit in your tests as well as on the code.


Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (fabien.delpierre@gmail.commailto:fabien.delpierre@gmail.com) wrote:

Hi folks,
I’m new to Test Kitchen and trying to make sense of it all. I’m also new to TDD (and programming in general) so the weird pseudocodey language used by RSpec messes with my head because I’m expecting code and it reads more like English.
Anyway.
Right now I’d like to see if I can use one of my nodes’ attributes to run tests.
Specifically, I have something like this:

attributes/default.rb:
case node[‘platform’]
when 'centos’
default[‘myrecipe’][‘packages’] = %w(package1 package2)
when 'ubuntu’
default[‘myrecipe’][‘packages’] = %w(package3 package4)
end

recipes/default.rb:
node[‘myrecipe’][‘packages’].each do |pkg|
package pkg
end

Now, in my tests, what I’d like is to do something like:

node[‘myrecipe’][‘packages’].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven’t tested it because I’m done for today but I looked at other people’s code on GitHub and found similar things, so I imagine that it works):
case os[‘family’]
when 'centos’
packages = %w(package1 package2)
when 'ubuntu’
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that’s nice, but it requires maintaining on top of the list of attributes in the attributes/default.rb file, hence my wondering whether there is a way for Kitchen to grab those values off the cookbook. Because that would be more efficient.

Is that possible? Or am I doomed?

This is exactly correct.

Tests should be verbose. They should not be DRY (don't repeat
yourself). Code reuse should be minimal.

The reason is because you are testing the possible outcomes. If your
inputs are variable, your outcomes are variable. Testing that you can
iterate over an array of things and get those things back out is
testing that the programming language works, not that the recipes
you're writing are doing what you want.

If you have an attribute that defines a list of packages, and you have
a recipe that iterates over that list creating package resources, you
should very well expect that Chef works, and will install each of
those packages. That is to say, the scenario you describe is testing
that Ruby and Chef work. Because both projects are very well tested,
we know that to be true.

A more valuable test in your post convergence is that the outcome of
having the package(s) installed is correct. If I install the zsh and
vim packages, I want to make sure that zsh is a valid, available
shell for my login users, and that vim is a valid executable program
in my $PATH.

The cycle of creating a machine, installing and running chef on it,
and then performing the test that the packages are there is very time
consuming for this purpose. I think you'd better spend your time
writing ChefSpec tests, rather than Serverspec tests, to verify this:
"if I set the attribute to have package zsh and vim, then I expect
those resources to exist." This is slightly ow value because again,
you're testing that Ruby works. However, it does protect you against
regressions in case the attribute name is changed, so input validation
is good, since Ruby is weakly typed.

These blog posts by Seth Vargo are great and chock full of information:

This post by Andrew Crump about post-convergence testing is pretty
solid, though a bit old in terms of specific tools and implementation:

And finally, I wrote this post recently discussing all the various
facets of testing infrastructure with Chef:

Hope this helps,
Joshua

On Tue, May 12, 2015 at 5:03 PM, Cassiano Leal cassianoleal@gmail.com wrote:

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s
definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like Chef
itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do what
you want.

In any case, ask yourself if you really need to test that the packages are
installed. If the package provides a service, you can make ServerSpec verify
that the service is running (it’s got a resource for that), or that a
certain port has a listening TCP socket or something else. Think about the
actual functionality you want to assert instead of the method used to put it
there.

If you still see value in testing that specific packages were installed,
then I guess you’ll have to be explicit in your tests as well as on the
code.

--
Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (fabien.delpierre@gmail.com)
wrote:

Hi folks,
I'm new to Test Kitchen and trying to make sense of it all. I'm also new to
TDD (and programming in general) so the weird pseudocodey language used by
RSpec messes with my head because I'm expecting code and it reads more like
English.
Anyway.
Right now I'd like to see if I can use one of my nodes' attributes to run
tests.
Specifically, I have something like this:

attributes/default.rb:
case node['platform']
when 'centos'
default['myrecipe']['packages'] = %w(package1 package2)
when 'ubuntu'
default['myrecipe']['packages'] = %w(package3 package4)
end

recipes/default.rb:
node['myrecipe']['packages'].each do |pkg|
package pkg
end

Now, in my tests, what I'd like is to do something like:

node['myrecipe']['packages'].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven't tested it because I'm done for
today but I looked at other people's code on GitHub and found similar
things, so I imagine that it works):
case os['family']
when 'centos'
packages = %w(package1 package2)
when 'ubuntu'
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that's nice, but it requires maintaining on top of
the list of attributes in the attributes/default.rb file, hence my wondering
whether there is a way for Kitchen to grab those values off the cookbook.
Because that would be more efficient.

Is that possible? Or am I doomed?

Thanks for finding that!

On Tue, May 12, 2015 at 10:10 PM, John Osborne <John.Osborne@synchronoss.com

wrote:

Fabien-

I implemented exactly what you’re looking for by following the test
fixture cookbook approach discussed in this blog article [1]. Using this, I
can reference the node attributes within my ServerSpec tests.

  • John

[1]
http://jakshi.com/blog/2014/05/12/accessing-chef-attributes-in-serverspec-tests/

From: Cassiano Leal
Reply-To: "chef@lists.opscode.com"
Date: Tuesday, May 12, 2015 at 7:03 PM
To: Fabien Delpierre, "chef@lists.opscode.com"
Subject: [chef] Re: Using node attributes in Kitchen ServerSpec tests

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s
definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like
Chef itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do
what you want.

In any case, ask yourself if you really need to test that the packages
are installed. If the package provides a service, you can make ServerSpec
verify that the service is running (it’s got a resource for that), or that
a certain port has a listening TCP socket or something else. Think about
the actual functionality you want to assert instead of the method used to
put it there.

If you still see value in testing that specific packages were installed,
then I guess you’ll have to be explicit in your tests as well as on the
code.

--
Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (fabien.delpierre@gmail.com)
wrote:

     Hi folks,

I'm new to Test Kitchen and trying to make sense of it all. I'm also new
to TDD (and programming in general) so the weird pseudocodey language used
by RSpec messes with my head because I'm expecting code and it reads more
like English.
Anyway.
Right now I'd like to see if I can use one of my nodes' attributes to run
tests.
Specifically, I have something like this:

attributes/default.rb:
case node['platform']
when 'centos'
default['myrecipe']['packages'] = %w(package1 package2)
when 'ubuntu'
default['myrecipe']['packages'] = %w(package3 package4)
end

recipes/default.rb:
node['myrecipe']['packages'].each do |pkg|
package pkg
end

Now, in my tests, what I'd like is to do something like:

node['myrecipe']['packages'].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven't tested it because I'm done
for today but I looked at other people's code on GitHub and found similar
things, so I imagine that it works):
case os['family']
when 'centos'
packages = %w(package1 package2)
when 'ubuntu'
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that's nice, but it requires maintaining on top
of the list of attributes in the attributes/default.rb file, hence my
wondering whether there is a way for Kitchen to grab those values off the
cookbook. Because that would be more efficient.

Is that possible? Or am I doomed?

So, essentially I'm wasting my time / doing it wrong? :slight_smile:
That's OK, all these concepts are pretty foreign to me at this point, I was
only introduced to TDD fairly recently and still don't really understand.
For me, as a beginner programmer, it seems like it made the learning curve
twice as steep, and doubled the time I spend coding, with no clear benefit
other than pleasing people who expect me to produce tests. I'll read the
blog posts you mentioned, thank you for your detailed answer!

On Wed, May 13, 2015 at 1:03 AM, Joshua Timberman joshua@chef.io wrote:

This is exactly correct.

Tests should be verbose. They should not be DRY (don't repeat
yourself). Code reuse should be minimal.

The reason is because you are testing the possible outcomes. If your
inputs are variable, your outcomes are variable. Testing that you can
iterate over an array of things and get those things back out is
testing that the programming language works, not that the recipes
you're writing are doing what you want.

If you have an attribute that defines a list of packages, and you have
a recipe that iterates over that list creating package resources, you
should very well expect that Chef works, and will install each of
those packages. That is to say, the scenario you describe is testing
that Ruby and Chef work. Because both projects are very well tested,
we know that to be true.

A more valuable test in your post convergence is that the outcome of
having the package(s) installed is correct. If I install the zsh and
vim packages, I want to make sure that zsh is a valid, available
shell for my login users, and that vim is a valid executable program
in my $PATH.

The cycle of creating a machine, installing and running chef on it,
and then performing the test that the packages are there is very time
consuming for this purpose. I think you'd better spend your time
writing ChefSpec tests, rather than Serverspec tests, to verify this:
"if I set the attribute to have package zsh and vim, then I expect
those resources to exist." This is slightly ow value because again,
you're testing that Ruby works. However, it does protect you against
regressions in case the attribute name is changed, so input validation
is good, since Ruby is weakly typed.

These blog posts by Seth Vargo are great and chock full of information:

This post by Andrew Crump about post-convergence testing is pretty
solid, though a bit old in terms of specific tools and implementation:

On the level: Testing your infrastructure - Chef Blog | Chef

And finally, I wrote this post recently discussing all the various
facets of testing infrastructure with Chef:

https://www.chef.io/blog/2015/04/21/overview-of-test-driven-infrastructure-with-chef/

Hope this helps,
Joshua

On Tue, May 12, 2015 at 5:03 PM, Cassiano Leal cassianoleal@gmail.com
wrote:

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s
definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like Chef
itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do what
you want.

In any case, ask yourself if you really need to test that the packages
are
installed. If the package provides a service, you can make ServerSpec
verify
that the service is running (it’s got a resource for that), or that a
certain port has a listening TCP socket or something else. Think about
the
actual functionality you want to assert instead of the method used to
put it
there.

If you still see value in testing that specific packages were installed,
then I guess you’ll have to be explicit in your tests as well as on the
code.

--
Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (fabien.delpierre@gmail.com
)
wrote:

Hi folks,
I'm new to Test Kitchen and trying to make sense of it all. I'm also new
to
TDD (and programming in general) so the weird pseudocodey language used
by
RSpec messes with my head because I'm expecting code and it reads more
like
English.
Anyway.
Right now I'd like to see if I can use one of my nodes' attributes to run
tests.
Specifically, I have something like this:

attributes/default.rb:
case node['platform']
when 'centos'
default['myrecipe']['packages'] = %w(package1 package2)
when 'ubuntu'
default['myrecipe']['packages'] = %w(package3 package4)
end

recipes/default.rb:
node['myrecipe']['packages'].each do |pkg|
package pkg
end

Now, in my tests, what I'd like is to do something like:

node['myrecipe']['packages'].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven't tested it because I'm done
for
today but I looked at other people's code on GitHub and found similar
things, so I imagine that it works):
case os['family']
when 'centos'
packages = %w(package1 package2)
when 'ubuntu'
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that's nice, but it requires maintaining on top
of
the list of attributes in the attributes/default.rb file, hence my
wondering
whether there is a way for Kitchen to grab those values off the cookbook.
Because that would be more efficient.

Is that possible? Or am I doomed?

It's hard to see the value of TDD at the beginning. But trust me...it
saves SO MUCH PAIN once you're working with a long lived code base.

I gave a talk on this (with examples in Rspec, through for a Rails code
base) called "Test Driven Development: A Love Story" a couple of years ago
http://confreaks.tv/videos/acr2013-test-driven-development-a-love-story

It's about how I passed through the five stages of grief in learning TDD
and how that grief turned to both sanity with the code bases I maintain and
re-ignited my love of programming.

On Thu, May 14, 2015 at 6:10 AM, Fabien Delpierre <
fabien.delpierre@gmail.com> wrote:

So, essentially I'm wasting my time / doing it wrong? :slight_smile:
That's OK, all these concepts are pretty foreign to me at this point, I
was only introduced to TDD fairly recently and still don't really
understand. For me, as a beginner programmer, it seems like it made the
learning curve twice as steep, and doubled the time I spend coding, with no
clear benefit other than pleasing people who expect me to produce tests.
I'll read the blog posts you mentioned, thank you for your detailed answer!

On Wed, May 13, 2015 at 1:03 AM, Joshua Timberman joshua@chef.io wrote:

This is exactly correct.

Tests should be verbose. They should not be DRY (don't repeat
yourself). Code reuse should be minimal.

The reason is because you are testing the possible outcomes. If your
inputs are variable, your outcomes are variable. Testing that you can
iterate over an array of things and get those things back out is
testing that the programming language works, not that the recipes
you're writing are doing what you want.

If you have an attribute that defines a list of packages, and you have
a recipe that iterates over that list creating package resources, you
should very well expect that Chef works, and will install each of
those packages. That is to say, the scenario you describe is testing
that Ruby and Chef work. Because both projects are very well tested,
we know that to be true.

A more valuable test in your post convergence is that the outcome of
having the package(s) installed is correct. If I install the zsh and
vim packages, I want to make sure that zsh is a valid, available
shell for my login users, and that vim is a valid executable program
in my $PATH.

The cycle of creating a machine, installing and running chef on it,
and then performing the test that the packages are there is very time
consuming for this purpose. I think you'd better spend your time
writing ChefSpec tests, rather than Serverspec tests, to verify this:
"if I set the attribute to have package zsh and vim, then I expect
those resources to exist." This is slightly ow value because again,
you're testing that Ruby works. However, it does protect you against
regressions in case the attribute name is changed, so input validation
is good, since Ruby is weakly typed.

These blog posts by Seth Vargo are great and chock full of information:

This post by Andrew Crump about post-convergence testing is pretty
solid, though a bit old in terms of specific tools and implementation:

On the level: Testing your infrastructure - Chef Blog | Chef

And finally, I wrote this post recently discussing all the various
facets of testing infrastructure with Chef:

https://www.chef.io/blog/2015/04/21/overview-of-test-driven-infrastructure-with-chef/

Hope this helps,
Joshua

On Tue, May 12, 2015 at 5:03 PM, Cassiano Leal cassianoleal@gmail.com
wrote:

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s
definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like
Chef
itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do
what
you want.

In any case, ask yourself if you really need to test that the packages
are
installed. If the package provides a service, you can make ServerSpec
verify
that the service is running (it’s got a resource for that), or that a
certain port has a listening TCP socket or something else. Think about
the
actual functionality you want to assert instead of the method used to
put it
there.

If you still see value in testing that specific packages were installed,
then I guess you’ll have to be explicit in your tests as well as on the
code.

--
Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (
fabien.delpierre@gmail.com)
wrote:

Hi folks,
I'm new to Test Kitchen and trying to make sense of it all. I'm also
new to
TDD (and programming in general) so the weird pseudocodey language used
by
RSpec messes with my head because I'm expecting code and it reads more
like
English.
Anyway.
Right now I'd like to see if I can use one of my nodes' attributes to
run
tests.
Specifically, I have something like this:

attributes/default.rb:
case node['platform']
when 'centos'
default['myrecipe']['packages'] = %w(package1 package2)
when 'ubuntu'
default['myrecipe']['packages'] = %w(package3 package4)
end

recipes/default.rb:
node['myrecipe']['packages'].each do |pkg|
package pkg
end

Now, in my tests, what I'd like is to do something like:

node['myrecipe']['packages'].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven't tested it because I'm done
for
today but I looked at other people's code on GitHub and found similar
things, so I imagine that it works):
case os['family']
when 'centos'
packages = %w(package1 package2)
when 'ubuntu'
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that's nice, but it requires maintaining on top
of
the list of attributes in the attributes/default.rb file, hence my
wondering
whether there is a way for Kitchen to grab those values off the
cookbook.
Because that would be more efficient.

Is that possible? Or am I doomed?

--

Nell Shamrell-Harrington — Software Engineer
206.745.0000 – nshamrell@chef.io – my: LinkedIn
https://www.linkedin.com/in/nellshamrell Twitter
http://www.twitter.com/nellshamrell

CHEF

WWW.CHEF.IO http://www.chef.io

TM

chef.io http://www.chef.io Blog http://www.chef.io/blog Facebook
https://www.facebook.com/getchefdotcom Twitter
https://twitter.com/chef Youtube https://www.youtube.com/getchef

Nell,

I finally got around to watching this. Thanks for the pointer, definitely
worth it.

Cheers,

Peter

On Fri, May 15, 2015 at 12:23 PM, Nell Shamrell nshamrell@chef.io wrote:

It's hard to see the value of TDD at the beginning. But trust me...it
saves SO MUCH PAIN once you're working with a long lived code base.

I gave a talk on this (with examples in Rspec, through for a Rails code
base) called "Test Driven Development: A Love Story" a couple of years ago
http://confreaks.tv/videos/acr2013-test-driven-development-a-love-story

It's about how I passed through the five stages of grief in learning TDD
and how that grief turned to both sanity with the code bases I maintain and
re-ignited my love of programming.

On Thu, May 14, 2015 at 6:10 AM, Fabien Delpierre <
fabien.delpierre@gmail.com> wrote:

So, essentially I'm wasting my time / doing it wrong? :slight_smile:
That's OK, all these concepts are pretty foreign to me at this point, I
was only introduced to TDD fairly recently and still don't really
understand. For me, as a beginner programmer, it seems like it made the
learning curve twice as steep, and doubled the time I spend coding, with no
clear benefit other than pleasing people who expect me to produce tests.
I'll read the blog posts you mentioned, thank you for your detailed answer!

On Wed, May 13, 2015 at 1:03 AM, Joshua Timberman joshua@chef.io wrote:

This is exactly correct.

Tests should be verbose. They should not be DRY (don't repeat
yourself). Code reuse should be minimal.

The reason is because you are testing the possible outcomes. If your
inputs are variable, your outcomes are variable. Testing that you can
iterate over an array of things and get those things back out is
testing that the programming language works, not that the recipes
you're writing are doing what you want.

If you have an attribute that defines a list of packages, and you have
a recipe that iterates over that list creating package resources, you
should very well expect that Chef works, and will install each of
those packages. That is to say, the scenario you describe is testing
that Ruby and Chef work. Because both projects are very well tested,
we know that to be true.

A more valuable test in your post convergence is that the outcome of
having the package(s) installed is correct. If I install the zsh and
vim packages, I want to make sure that zsh is a valid, available
shell for my login users, and that vim is a valid executable program
in my $PATH.

The cycle of creating a machine, installing and running chef on it,
and then performing the test that the packages are there is very time
consuming for this purpose. I think you'd better spend your time
writing ChefSpec tests, rather than Serverspec tests, to verify this:
"if I set the attribute to have package zsh and vim, then I expect
those resources to exist." This is slightly ow value because again,
you're testing that Ruby works. However, it does protect you against
regressions in case the attribute name is changed, so input validation
is good, since Ruby is weakly typed.

These blog posts by Seth Vargo are great and chock full of information:

This post by Andrew Crump about post-convergence testing is pretty
solid, though a bit old in terms of specific tools and implementation:

On the level: Testing your infrastructure - Chef Blog | Chef

And finally, I wrote this post recently discussing all the various
facets of testing infrastructure with Chef:

https://www.chef.io/blog/2015/04/21/overview-of-test-driven-infrastructure-with-chef/

Hope this helps,
Joshua

On Tue, May 12, 2015 at 5:03 PM, Cassiano Leal cassianoleal@gmail.com
wrote:

The “weird pseudocodey language used by RSpec” is called Ruby, and it’s
definitely not pseudo in any sense. :slight_smile:

It’s true that RSpec implements a DSL on top of Ruby, very much like
Chef
itself. It’s still 100% Ruby in both cases though.

Now, about your specific problem, I don’t think there is a way to do
what
you want.

In any case, ask yourself if you really need to test that the packages
are
installed. If the package provides a service, you can make ServerSpec
verify
that the service is running (it’s got a resource for that), or that a
certain port has a listening TCP socket or something else. Think about
the
actual functionality you want to assert instead of the method used to
put it
there.

If you still see value in testing that specific packages were
installed,
then I guess you’ll have to be explicit in your tests as well as on the
code.

--
Cassiano Leal

On 12 May 2015 at 22:18:51, Fabien Delpierre (
fabien.delpierre@gmail.com)
wrote:

Hi folks,
I'm new to Test Kitchen and trying to make sense of it all. I'm also
new to
TDD (and programming in general) so the weird pseudocodey language
used by
RSpec messes with my head because I'm expecting code and it reads more
like
English.
Anyway.
Right now I'd like to see if I can use one of my nodes' attributes to
run
tests.
Specifically, I have something like this:

attributes/default.rb:
case node['platform']
when 'centos'
default['myrecipe']['packages'] = %w(package1 package2)
when 'ubuntu'
default['myrecipe']['packages'] = %w(package3 package4)
end

recipes/default.rb:
node['myrecipe']['packages'].each do |pkg|
package pkg
end

Now, in my tests, what I'd like is to do something like:

node['myrecipe']['packages'].each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

I can do something like this (note I haven't tested it because I'm
done for
today but I looked at other people's code on GitHub and found similar
things, so I imagine that it works):
case os['family']
when 'centos'
packages = %w(package1 package2)
when 'ubuntu'
packages = %w(package3 package4)
end

packages.each do |pkg|
describe package(pkg) do
it { should be_installed }
end
end

So assuming this works, that's nice, but it requires maintaining on
top of
the list of attributes in the attributes/default.rb file, hence my
wondering
whether there is a way for Kitchen to grab those values off the
cookbook.
Because that would be more efficient.

Is that possible? Or am I doomed?

--

Nell Shamrell-Harrington — Software Engineer
206.745.0000 – nshamrell@chef.io – my: LinkedIn
https://www.linkedin.com/in/nellshamrell Twitter
http://www.twitter.com/nellshamrell

CHEF

WWW.CHEF.IO http://www.chef.io

TM

chef.io http://www.chef.io Blog http://www.chef.io/blog Facebook
https://www.facebook.com/getchefdotcom Twitter
https://twitter.com/chef Youtube https://www.youtube.com/getchef

--

Peter Burkholder — Customer Success Engineer

Unavailability: June 22-26 - Team Offsite

301-204-5767 – pburkholder@chef.io – *my: *Linkedin
http://www.linkedin.com/in/pburkholder Twitter
http://www.twitter.com/pburkholder Cal
https://www.google.com/calendar/embed?src=pburkholder%40chef.io&mode=WEEK
endar

CHEF

CHEF.IO http://www.chef.io/

TM

chef.io http://www.chef.io/ Blog http://www.chef.io/blog/ Facebook
https://www.facebook.com/getchefdotcom Twitter
https://twitter.com/chef Youtube https://www.youtube.com/getchef