Contributors30 minutes | Test Kitchen enables you to run your cookbooks in a temporary environment that resembles production. With Test Kitchen, you confirm that things are working before you deploy your code to a test, preproduction, or production environment. Many users incorporate this kind of local development as part of their overall Chef workflow. |
In this part, you'll run through the Test Kitchen workflow to get the hang of things. You'll apply the web server cookbook you wrote in the _Manage a node with Chef server_ module on a local test instance.

 | In this step, Test Kitchen creates an instance of your virtual environment, for example, a Windows Server virtual machine. |
 | In this step, Test Kitchen applies your cookbook to the virtual environment. |
 | In this step, you connect to your virtual environment, typically over Remote Desktop or WinRM. |
 | In this step, you manually verify that your virtual environment is configured as you expect. |
 | In this step, Test Kitchen shuts down and destroys your virtual environment. |
In this module, you perform the verify step manually. In practice, you typically write tests that automatically verify whether your configuration works as you expect. You'll learn about local testing in a future module.
Here, you'll get a copy of the web server cookbook that you created in the earlier modules. Then you'll apply that cookbook on a Windows Server virtual machine. Then you'll verify that everything's working. Finally, you'll destroy the instance.
1. Get the learn_chef_iis cookbook from GitHub
In the Learn the Chef basics and Manage a node with Chef server modules, you wrote a cookbook named learn_chef_iis that configures IIS web server. You'll run that cookbook on your test instance.
If you still have the learn_chef_iis cookbook on your system, you're all set up. Otherwise, follow these steps to get it.
Start by creating the ~/learn-chef/cookbooks directory if it does not already exist.
Windows PowerShell: ~
PS > | mkdir ~/learn-chef/cookbooks
|
Now cd there.
Windows PowerShell: ~
PS > | cd ~/learn-chef/cookbooks
|
Next, clone the learn_chef_iis cookbook from GitHub.
Windows PowerShell: ~/learn-chef/cookbooks
PS > | git clone https://github.com/learn-chef/learn_chef_iis.gitCloning into 'learn_chef_iis'...
|
Now cd there.
Windows PowerShell: ~/learn-chef/cookbooks
PS > | cd ~/learn-chef/cookbooks/learn_chef_iis
|
The contents of ~/learn-chef/cookbooks/learn_chef_iis is the same as what you built in the Manage a node with Chef server module. You can examine this directory to familiarize yourself with its contents.
| Remember that Chef Supermarket is also a place for the community to share cookbooks. You'll learn more about community cookbooks in later modules. |
2. Create the Test Kitchen configuration file
When you use the chef generate cookbook command to create a cookbook, Chef creates a file named .kitchen.yml in the root directory of your cookbook. .kitchen.yml defines what's needed to run Test Kitchen, including which virtualization provider to use, how to run Chef, and what platforms to run your code on.
Here's what the initial .kitchen.yml file looks like.
Editor: ~/learn-chef/cookbooks/learn_chef_iis/.kitchen.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| ---
driver:
name: vagrant
boot_timeout: 1200
gui: false
provisioner:
name: chef_zero
verifier:
name: inspec
transport:
name: winrm
elevated: true
username: Administrator
password: Pass@word1
platforms:
- name: windows-2012R2
driver:
customize:
memory: 2048
suites:
- name: default
run_list:
- recipe[learn_chef_iis::default]
verifier:
inspec_tests:
- test/smoke/default
attributes: |
| In the latest releases of Test Kitchen, the .kitchen.yml file is named without the leading dot and will no longer be hidden. For example, kitchen.yml. However, the old format with the leading dot will remain backward compatible. |
We provide this configuration for the Vagrant and VirtualBox version of this module. To configure Test Kitchen to create Windows Server instances on Hyper-V, start by modifying .kitchen.yml like this.
Editor: ~/learn-chef/cookbooks/learn_chef_iis/.kitchen.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| ---
driver:
name: hyperv
parent_vhd_folder: C:\Hyper-V
parent_vhd_name: WindowsServer2012R2.vhdx
vm_switch: ExternalSwitch
memory_startup_bytes: 2GB
provisioner:
name: chef_zero
transport:
password: H24?6;H.QaV8JP2&
elevated: true
verifier:
name: inspec
platforms:
- name: windows-2012r2
suites:
- name: default
run_list:
- recipe[learn_chef_iis::default]
verifier:
inspec_tests:
- test/smoke/default
attributes: |
| In the latest releases of Test Kitchen, you won't have to specify nearly as much of the preceding configuration. |
Next, replace these values:
password with the Administrator password you specified when you built your base virtual machine.parent_vhd_folder, parent_vhd_name and vm_switch with your names if you chose names other than the ones shown on the previous page.
Test Kitchen can manage more than one instance at a time to enable you to test your cookbooks on multiple platforms. The default configuration creates both an Ubuntu and a CentOS virtual machine. Since we want only Windows Server, the platforms sections contains only windows-2012r2.
Here's how the .kitchen.yml file breaks down.
- driver specifies the software that manages the machine. We're using the Hyper-V Test Kitchen driver (list of other popular drivers).
- provisioner specifies how to run Chef. We use
chef_zero because it enables you to mimic a Chef server environment on your local machine. This allows us to work with node attributes and other Chef server features. - transport specifies how to execute commands remotely on the test instance. WinRM is the default transport on Windows; SSH is the default on all other operating systems.
- verifier specifies which application to use when running automated tests. You'll learn more about automated testing in a future module.
- platforms specifies the target operating systems. We're targeting just one – Windows Server 2012 R2.
- suites specifies what we want to apply to the virtual environment. You can have more than one suite. We define just one, named
default. This is where we provide the run-list, which defines which recipes to run and in the order to run them. Your run-list contains one recipe – the learn_chef_iis cookbook's default recipe.
The Chef documentation explains the structure of the .kitchen.yml file in greater detail, and also explains more about the available settings.
3. Create the Test Kitchen instance
Now you'll provision a virtual machine to serve as your test environment. This is the kitchen create step in our workflow.

We often call the set of virtual environments that's created by Test Kitchen simply a kitchen.
From the ~/learn-chef/cookbooks/learn_chef_iis directory, run kitchen list to see what's in the kitchen.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen listInstance Driver Provisioner Verifier Transport Last Action Last Errordefault-windows-2012r2 Hyperv ChefZero Inspec Winrm <Not Created> <None>
|
Our kitchen includes just one instance – a Windows Server 2012 R2 virtual machine that's configured to run the default suite. The Last Action column shows that the virtual machine is not yet created.
Create the instance now by running kitchen create.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen create-----> Starting Kitchen (v1.15.0)-----> Creating <default-windows-2012r2>... Creating differencing disk for default-windows-2012r2. Created differencing disk for default-windows-2012r2. Checking for existing virtual machine. Creating virtual machine for default-windows-2012r2. Created virtual machine for default-windows-2012r2. [WinRM] Established Hyper-V instance <default-windows-2012r2> created. Finished creating <default-windows-2012r2> (1m5.34s).-----> Kitchen is finished. (1m9.37s)
|
| If you need to destroy your instance before you complete this module, run kitchen destroy. You can later run kitchen create to pick back up where you left off on a fresh instance. |
Now run kitchen list again.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen listInstance Driver Provisioner Verifier Transport Last Action Last Errordefault-windows-2012r2 Hyperv ChefZero Inspec Winrm Created <None>
|
The Last Action column now shows that the virtual machine has been created.
4. Apply the learn_chef_iis cookbook to your Test Kitchen instance
Now run kitchen converge to apply the cookbook to the Windows Server virtual machine.

Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen converge-----> Starting Kitchen (v1.15.0)-----> Converging <default-windows-2012r2>... Preparing files for transfer Preparing dna.json Resolving cookbook dependencies with Berkshelf 5.6.0... Removing non-cookbook files before transfer Preparing validation.pem Preparing client.rb-----> Installing Chef Omnibus (install only if missing) Downloading package from https://packages.chef.io/files/stable/chef/12.19.36/windows/2012r2/chef-client-12.19.36-1-x64.msi Download complete. Successfully verified C:\Users\ADMINI~1\AppData\Local\Temp\chef-client-12.19.36-1-x64.msi Installing Chef Omnibus package C:\Users\ADMINI~1\AppData\Local\Temp\chef-client-12.19.36-1-x64.msi Installation complete Transferring files to <default-windows-2012r2> Starting Chef Client, version 12.19.36 [2017-03-15T15:04:57-07:00] INFO: *** Chef 12.19.36 *** [2017-03-15T15:04:57-07:00] INFO: Platform: x64-mingw32 [2017-03-15T15:04:57-07:00] INFO: Chef-client pid: 1360 Creating a new client identity for default-windows-2012r2 using the validator key. [2017-03-15T15:05:33-07:00] INFO: Client key C:\Users\ADMINI~1\AppData\Local\Temp\kitchen\client.pem is not present - registering [2017-03-15T15:05:33-07:00] INFO: HTTP Request Returned 404 Not Found: Object not found: chefzero://localhost:8889/nodes/default-windows-2012r2 [2017-03-15T15:05:33-07:00] INFO: Setting the run_list to ["recipe[learn_chef_iis::default]"] from CLI options [2017-03-15T15:05:33-07:00] INFO: Run List is [recipe[learn_chef_iis::default]] [2017-03-15T15:05:33-07:00] INFO: Run List expands to [learn_chef_iis::default] [2017-03-15T15:05:33-07:00] INFO: Starting Chef Run for default-windows-2012r2 [2017-03-15T15:05:33-07:00] INFO: Running start handlers [2017-03-15T15:05:33-07:00] INFO: Start handlers complete. [2017-03-15T15:05:33-07:00] INFO: HTTP Request Returned 404 Not Found: Object not found: resolving cookbooks for run list: ["learn_chef_iis::default"] [2017-03-15T15:05:33-07:00] INFO: Loading cookbooks [learn_chef_iis@0.1.0] Synchronizing Cookbooks: [2017-03-15T15:05:33-07:00] INFO: Storing updated cookbooks/learn_chef_iis/recipes/default.rb in the cache. [2017-03-15T15:05:33-07:00] INFO: Storing updated cookbooks/learn_chef_iis/templates/Default.htm.erb in the cache. [2017-03-15T15:05:33-07:00] INFO: Storing updated cookbooks/learn_chef_iis/README.md in the cache. [2017-03-15T15:05:33-07:00] INFO: Storing updated cookbooks/learn_chef_iis/metadata.json in the cache. - learn_chef_iis (0.1.0) Installing Cookbook Gems: Compiling Cookbooks... Converging 3 resources Recipe: learn_chef_iis::default * powershell_script[Install IIS] action run[2017-03-15T15:05:33-07:00] INFO: Processing powershell_script[Install IIS] action run (learn_chef_iis::default line 6) [2017-03-15T15:05:33-07:00] INFO: Processing powershell_script[Guard resource] action run (dynamically defined) [execute] WARNING: Windows automatic updating is not enabled. To ensure that your newly-installed role or feature is automatically updated, turn on Windows Update. Success Restart Needed Exit Code Feature Result ------- -------------- --------- -------------- True No Success {Common HTTP Features, Default Documen... [2017-03-15T15:06:03-07:00] INFO: powershell_script[Install IIS] ran successfully - execute "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Bypass -InputFormat None -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20170315-1360-cfoqpd.ps1" * windows_service[w3svc] action enable[2017-03-15T15:06:03-07:00] INFO: Processing windows_service[w3svc] action enable (learn_chef_iis::default line 12) (up to date) * windows_service[w3svc] action start[2017-03-15T15:06:03-07:00] INFO: Processing windows_service[w3svc] action start (learn_chef_iis::default line 12) (up to date) * template[c:\inetpub\wwwroot\Default.htm] action create[2017-03-15T15:06:03-07:00] INFO: Processing template[c:\inetpub\wwwroot\Default.htm] action create (learn_chef_iis::default line 16) [2017-03-15T15:06:03-07:00] INFO: template[c:\inetpub\wwwroot\Default.htm] created file c:\inetpub\wwwroot\Default.htm - create new file c:\inetpub\wwwroot\Default.htm - update content in file c:\inetpub\wwwroot\Default.htm from none to a7298b --- c:\inetpub\wwwroot\Default.htm 2017-03-15 15:06:03.000000000 -0700 +++ c:\inetpub\wwwroot/chef-Default20170315-1360-1ck7p0a.htm 2017-03-15 15:06:03.000000000 -0700 @@ -1 +1,6 @@ +<html> + <body> + <h1>hello world</h1> + </body> +</html> [2017-03-15T15:06:03-07:00] INFO: Chef Run complete in 30.303773 seconds Running handlers: [2017-03-15T15:06:03-07:00] INFO: Running report handlers Running handlers complete [2017-03-15T15:06:03-07:00] INFO: Report handlers complete Chef Client finished, 2/4 resources updated in 01 minutes 06 seconds Finished converging <default-windows-2012r2> (2m44.34s).-----> Kitchen is finished. (2m48.30s)
|
| We use the term converge to describe the process of bringing a system closer to its desired state. When you see the word converge, think test and repair. |
| In practice, if you had more than one platform specified in your .kitchen.yml file, then you should specify the platform/instance you want to test your cookbook on when you run kitchen converge. For example, kitchen converge default-windows-2012r2. Otherwise, Test Kitchen would test your cookbook on all the platforms specified in your .kitchen.yml file. Incidentally, the platform specification is a concatenation of the suites name and the platform name in your .kitchen.yml. Therefore, default-windows-2012r2 is derived from this exerpt from your .kitchen.yml: |
Terminal: Example
| platforms: - name: windows-2012r2 suites: - name: default
|
Test Kitchen runs chef-client on the instance. When the chef-client run completes successfully, Test Kitchen exits with exit code 0. Run the following to check the exit code.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
If you receive a result other than 0, fix the errors that were reported. Then run kitchen converge to apply the changes and again check the exit code.
Run kitchen list to see the latest status.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen listInstance Driver Provisioner Verifier Transport Last Action Last Errordefault-windows-2012r2 Hyperv ChefZero Inspec Winrm Converged <None>
|
kitchen converge takes longer the first time you run it on a new instance because Test Kitchen needs to install the Chef tools. Run kitchen converge a second time to see how much faster it is.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen converge-----> Starting Kitchen (v1.15.0)-----> Converging <default-windows-2012r2>... Preparing files for transfer Preparing dna.json Resolving cookbook dependencies with Berkshelf 5.6.0... Removing non-cookbook files before transfer Preparing validation.pem Preparing client.rb-----> Chef Omnibus installation detected (install only if missing) Transferring files to <default-windows-2012r2> Starting Chef Client, version 12.19.36 [2017-03-15T15:09:35-07:00] INFO: *** Chef 12.19.36 *** [2017-03-15T15:09:35-07:00] INFO: Platform: x64-mingw32 [2017-03-15T15:09:35-07:00] INFO: Chef-client pid: 2640 [2017-03-15T15:10:11-07:00] INFO: Setting the run_list to ["recipe[learn_chef_iis::default]"] from CLI options [2017-03-15T15:10:11-07:00] INFO: Run List is [recipe[learn_chef_iis::default]] [2017-03-15T15:10:11-07:00] INFO: Run List expands to [learn_chef_iis::default] [2017-03-15T15:10:11-07:00] INFO: Starting Chef Run for default-windows-2012r2 [2017-03-15T15:10:11-07:00] INFO: Running start handlers [2017-03-15T15:10:11-07:00] INFO: Start handlers complete. [2017-03-15T15:10:11-07:00] INFO: HTTP Request Returned 404 Not Found: Object not found: resolving cookbooks for run list: ["learn_chef_iis::default"] [2017-03-15T15:10:11-07:00] INFO: Loading cookbooks [learn_chef_iis@0.1.0] Synchronizing Cookbooks: - learn_chef_iis (0.1.0) Installing Cookbook Gems: Compiling Cookbooks... Converging 3 resources Recipe: learn_chef_iis::default * powershell_script[Install IIS] action run[2017-03-15T15:10:11-07:00] INFO: Processing powershell_script[Install IIS] action run (learn_chef_iis::default line 6) [2017-03-15T15:10:11-07:00] INFO: Processing powershell_script[Guard resource] action run (dynamically defined) [2017-03-15T15:10:12-07:00] INFO: powershell_script[Guard resource] ran successfully (skipped due to not_if) * windows_service[w3svc] action enable[2017-03-15T15:10:12-07:00] INFO: Processing windows_service[w3svc] action enable (learn_chef_iis::default line 12) (up to date) * windows_service[w3svc] action start[2017-03-15T15:10:12-07:00] INFO: Processing windows_service[w3svc] action start (learn_chef_iis::default line 12) (up to date) * template[c:\inetpub\wwwroot\Default.htm] action create[2017-03-15T15:10:12-07:00] INFO: Processing template[c:\inetpub\wwwroot\Default.htm] action create (learn_chef_iis::default line 16) (up to date) [2017-03-15T15:10:12-07:00] INFO: Chef Run complete in 1.316228 seconds Running handlers: [2017-03-15T15:10:12-07:00] INFO: Running report handlers Running handlers complete [2017-03-15T15:10:12-07:00] INFO: Report handlers complete Chef Client finished, 0/4 resources updated in 36 seconds Finished converging <default-windows-2012r2> (0m54.95s).-----> Kitchen is finished. (0m58.29s)
|
This run was faster not only because the instance already had the Chef tools installed, but also because it was already in the desired state, so Chef had no work to do.
5. Verify that your Test Kitchen instance is configured as expected
The next step in the Test Kitchen workflow is to verify the configuration.

In practice, you typically write automated tests that verify whether your instance is configured as you expect. Having automated tests enables you to quickly verify that your configuration works as you add features to your cookbook. In fact, many Chef users take a test-driven approach, where you write your tests first before you write any Chef code.
You'll learn more about automated testing in a future module. For now, let's verify the configuration manually. Recall that the learn_chef_iis cookbook configures IIS and sets the home page to display "hello world". An easy way to verify this is to log into your test instance and run Invoke-WebRequest localhost.
The kitchen login command is the most common way to access your test instance. This command creates a WinRM connection into your instance and enables you to explore your test instance and verify its configuration.
Because you only want to run Invoke-WebRequest localhost, you can run kitchen exec to run a single command.
Run the following command to verify the contents of your web server's home page.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen exec -c '(Invoke-WebRequest -UseBasicParsing localhost).Content'-----> Execute command on default-windows-2012r2. <html> <body> <h1>hello world</h1> </body> </html>
|
You see that the web page contains "hello world" as expected.
Connecting to your Windows Server instance over Remote Desktop
Here, you ran kitchen exec to verify your configuration over WinRM. Although not required, you can also connect over Remote Desktop. Remote Desktop gives you full access to your Windows Server instance through its graphical interface. The way you connect to your instance depends on which driver you're using.
When you use the Hyper-V driver, login to your instance, default-windows-2012r2, through Hyper-V Manager. Login as Administrator and use the same password that you set when you created the base virtual machine.

6. Delete the Test Kitchen instance
We're all done with our virtual machine, so now run the kitchen destroy command to delete it.

Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen destroy-----> Starting Kitchen (v1.15.0)-----> Destroying <default-windows-2012r2>... Checking for existing virtual machine. Found an exising VM with an ID: 6c4da3e3-f93a-4af8-8c80-9351a725dab3 Deleting virtual machine for default-windows-2012r2 Deleted virtual machine for default-windows-2012r2 Removing the differencing disk for default-windows-2012r2. Removed the differencing disk for default-windows-2012r2. The Hyper-V instance <default-windows-2012r2> has been removed. Finished destroying <default-windows-2012r2> (0m10.27s).-----> Kitchen is finished. (0m13.96s)
|
Run kitchen list and you'll see that the Last Action column shows that the virtual machine no longer exists.
Windows PowerShell: ~/learn-chef/cookbooks/learn_chef_iis
PS > | kitchen listInstance Driver Provisioner Verifier Transport Last Action Last Errordefault-windows-2012r2 Hyperv ChefZero Inspec Winrm <Not Created> <None>
|