This guide will get you using Lens in just a few minutes.

Install Lens

You can download Lens with one command:

php -r "$file = 'C:\\Lens\\lens'; $url = ''; @mkdir(dirname($file), 0755, true); copy(\"$url.phar\", $file); copy(\"$url.bat\", \"$file.bat\");"

But you’re not done yet! You’ll also need to add Lens to your system path.

First, open the “System Properties” dialog by running this command in the Windows shell:


Now click on the “Environment Variables” button: Under the "System variables" section, find the “Path” value (you may need to scroll a bit) and add “;C:\Lens” to the end.

You can download Lens with one command:

sudo php -r '$file = "/usr/local/bin/lens"; copy("", $file); chmod($file, 0755);'

You can download Lens with one command:

sudo php -r '$file = "/usr/local/bin/lens"; @mkdir(dirname($file), 0755, true); copy("", $file); chmod($file, 0755);'

You can also get Lens through Composer or Git.

Write a test

Here’s a simple test:

<?php // Test $x = 1 + 1; // Effect $x = 2;

Run Lens to see the results:

lens Math.php # Passed tests: 1

Congratulations! You’ve written your first test!

Hmm! What would happen if you were to change that expected effect in the Effect section to something else? Would Lens catch the discrepancy?

Write a test for your project

Now let’s test an actual class from your project. Which class will you choose?

Suppose your source code looks something like this:

<?php namespace Example; use RangeException; class Math { public function divide($m, $n) { if ($n === 0) { throw new RangeException(); } return $m / $n; } }

Let’s write the unit tests:

<?php namespace Example; use RangeException; // Test $math = new Math(); $c = $math->divide($a, $b); // Cause $a = 1; $b = 2; // Effect $c = 0.5; // Cause $a = 1; $b = 0; // Effect throw new RangeException();

Download this example

Run Lens to see the results:

lens # Passed tests: 2

Congratulations! You can test object-oriented code!

You can repeat the same test with many different “Cause” and “Effect” sections, until you’re completely satisfied that the “Test” code is fully tested.

How does it work?

Under the hood, Lens transforms each test case into code snippets like this:


// Cause $a = 1; $b = 2; // Test $math = new Math(); $c = $math->divide($a, $b);


// Effect $c = 0.5;

Lens runs all of these code snippets at the same time, in parallel processes. After the dust has settled, Lens checks that all of the expected side effects did indeed happen. If there were any additional or missing side effects, then Lens will fail the test and alert you.

You can test anything this way. If you know what the side effects ought to be, then you can test it.

Oh, and if the side effects ever grow to be too much? You can add an unclean class to the list of mocks in your configuration file: Lens will replace those classes with mock objects. That way, you can encapsulate messy side effects so they don’t leak through into your other tests. You’ll simply list the public method calls that you were expecting, instead of the deep side effects that would have been invoked if the code had been allowed to run live.

In general, though, it’s helpful to let your classes run as live code, so you get the benefits of integration testing along with the benefits of unit testing. But we leave that choice to you.

See the results

Now that you’ve written some tests, a “lens/coverage” directory has appeared:

Code coverage: directory view
Code coverage: file view

Be sure to check out that coverage directory in your web browser, since it’s rather useful!

Integrate with your tools