From 9898cd9a954e702221d32d6aaf7e725ee12c7f6b Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 2 Jun 2012 12:56:10 +0200 Subject: [PATCH] MINOR Improved testing docs --- .../testing/create-silverstripe-test.md | 38 +++++----------- docs/en/topics/testing/index.md | 10 +---- .../testing/testing-guide-troubleshooting.md | 44 +++++++++++++++++++ 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/docs/en/topics/testing/create-silverstripe-test.md b/docs/en/topics/testing/create-silverstripe-test.md index 4d0db5ae1..ea1bd86f3 100644 --- a/docs/en/topics/testing/create-silverstripe-test.md +++ b/docs/en/topics/testing/create-silverstripe-test.md @@ -5,20 +5,12 @@ provides us the basics of creating unit tests. :::php objFromFixture($className, $identifier)** can be used to select one of the objects named in your fixture file. To identify to the object, we provide a class name and an identifier. The identifier is specified in the YML file but not saved in the database anywhere. objFromFixture() looks the `[api:DataObject]` up in memory rather than using the database. This means that you can use it to test the functions responsible for looking up content in the database. -* **$this->assertEquals()** is one of the many assert... functions that PHPUnit provides us. See below for more -information. - ## Assertion commands -**$this->assertEquals()** is an example of an assertion function. These functions form the basis of our tests - a test +**$this->assertEquals()** is an example of an assertion function. +These functions form the basis of our tests - a test fails if and only if one or more of the assertions fail. - - -There are many assertions available: - -* See [the PHPUnit manual chapter 22](http://www.phpunit.de/manual/current/en/api.html#api.assert) +See [the PHPUnit manual](http://www.phpunit.de/manual/current/en/api.html#api.assert) for a listing of all PHPUnit's built-in assertions. -* **$this->assertEmailSent($to, $from, $subject, $content)**: When an email is "sent" during a test run, it's not -actually sent. Instead, it is logged in an internal register. You can use assertEmailSent() to verify that an email -was sent. Each of the arguments can be a string, for an exact match, or, a preg_match() compatible regular expression, -if it starts with "/". + +The `[api:SapphireTest]` class comes with additional assertions which are more +specific to the framework, e.g. `[assertEmailSent](api:SapphireTest->assertEmailSent())` +which can simulate sending emails through the `Email->send()` API without actually +using a mail server (see the [testing emails](email-sending)) guide. ## The Database YAML file diff --git a/docs/en/topics/testing/index.md b/docs/en/topics/testing/index.md index f39ef75a1..6c833904b 100644 --- a/docs/en/topics/testing/index.md +++ b/docs/en/topics/testing/index.md @@ -8,8 +8,6 @@ The SilverStripe core contains various features designed to simplify the process * [Troubleshooting](testing-guide-troubleshooting): Frequently asked questions list for testing issues * [Why Unit Test?](why-test): Why should you test and how to start testing -## Introduction - If you are familiar with PHP coding but new to unit testing, you should read the [Introduction](/topics/testing) and check out Mark's presentation [Getting to Grips with SilverStripe Testing](http://www.slideshare.net/maetl/getting-to-grips-with-silverstripe-testing). @@ -99,7 +97,6 @@ Some people may note that we have used the same naming convention as Ruby on Rai Tutorials and recipes for creating tests using the SilverStripe framework: * **[Create a SilverStripe Test](/topics/testing/create-silverstripe-test)** -* **Load Test Fixtures** * **[Create a Functional Test](/topics/testing/create-functional-test)** * **[Test Outgoing Email Sending](/topics/testing/email-sending)** @@ -145,9 +142,4 @@ understand the problem space and discover suitable APIs for performing specific **Behavior Driven Development (BDD):** An extension of the test-driven programming style, where tests are used primarily for describing the specification of how code should perform. In practice, there's little or no technical difference - it all comes down to language. In BDD, the usual terminology is changed to reflect this change of focus, so *Specification* -is used in place of *Test Case*, and *should* is used in place of *expect* and *assert*. - - -## Feedback - -If you have a topic you would like covered in these section please ask for it on our [Bug Tracker](http://open.silverstripe.org) +is used in place of *Test Case*, and *should* is used in place of *expect* and *assert*. \ No newline at end of file diff --git a/docs/en/topics/testing/testing-guide-troubleshooting.md b/docs/en/topics/testing/testing-guide-troubleshooting.md index 3c615ce0b..812aae5cf 100644 --- a/docs/en/topics/testing/testing-guide-troubleshooting.md +++ b/docs/en/topics/testing/testing-guide-troubleshooting.md @@ -15,3 +15,47 @@ It can be fixed by running the following commands: pear install -f phpunit/DbUnit pear install -f phpunit/PHPUnit_MockObject pear install -f phpunit/PHPUnit_Selenium + +## My tests fail seemingly random when comparing database IDs + +When defining fixtures in the YML format, you only assign aliases +for them, not direct database IDs. Even if you insert only one record +on a clean database, it is not guaranteed to produce ID=1 on every run. +So to make your tests more robust, use the aliases rather than hardcoded IDs. + +Also, some databases don't return records in a consistent sort order +unless you explicitly tell them to. If you don't want to test sort order +but rather just the returned collection, + + :::php + $myPage = $this->objFromFixture('Page', 'mypage'); + $myOtherPage = $this->objFromFixture('Page', 'myotherpage'); + $pages = DataObject::get('Page'); + // Bad: Assumptions about IDs and their order + $this->assertEquals(array(1,2), $pages->column('ID')); + // Good: Uses actually created IDs, independent of their order + $this->assertContains($myPage->ID, $pages->column('ID')); + $this->assertContains($myOtherPage->ID, $pages->column('ID')); + +## My fixtures are getting complicated, how do I inspect their database state? + +Fixtures are great because they're easy to define through YML, +but sometimes can be a bit of a blackbox when it comes to the actual +database state they create. These are temporary databases, which are +destructed directly after the test run - which is intentional, +but not very helpful if you want to verify that your fixtures have been created correctly. + +SilverStripe comes with a URL action called `dev/tests/startsession`. +When called through a web browser, it prompts for a fixture file +which it creates a new database for, and sets it as the current database +in this browser session until you call `dev/tests/endsession`. + +For more advanced users, you can also have a look in the `[api:YamlFixture]` +class to see what's going on behind the scenes. + +## My database server is cluttered with `tmpdb...` databases + +This is a common problem due to aborted test runs, +which don't clean up after themselves correctly +(mostly because of a fatal PHP error in the tests). +The easiest way to get rid of them is a call to `dev/tests/cleanupdb`. \ No newline at end of file