Since tests take long to run, it has become a habit of many to temporarily comment out tests in test cases that do not have any failures. I'm probably doing that two times each day.

So here comes the conclusion: Only re-run test case methods that had failures.

We likely want to properly store the method name in an own column for recorded assertions, but preg_match() worked out for now.

--
That said. It's the first time I'm really looking at the actual code of Simpletest module, and the module's code clearly needs some love.

Comments

c960657’s picture

Status: Needs review » Needs work

This have been on my wish list for ages.

Based on a rudimentary review and test, this looks good.

A style nit:

+function simpletest_run_tests(array $test_list, $reporter = 'drupal', array $failed_methods = array()) {

I think $failed_methods should rather be named something like $test_methods—whether they failed in the last test run is not really relevant for the current test run (and I guess you could imagine other cases where you want to run only a specific test function).

I think would be more intuitive if the method array immediately followed the test array in function argument lists, or perhaps the two could be merged into one array like array('class1' => TRUE, 'class2' => array('testFoo')) (meaning run everything in class1 but only testFoo() in class2). I think this will make the new feature more like an integrated part of the API.

The preg_match does not work with code like this:

  function testFoo() {
    $this->bar();
    $this->assertTrue(TRUE);
  }
  function bar() {
    $divide_by_zero = 1 / 0;
  }

When I try to run the failed test, it completes a test run with no tests (I think) and ends up with this error message:

Error message
No test results to display.

       'fail' => t('Fail (@count)', array('@count' => count($filter['fail']))),
+      'fail_methods' => t('Failed methods only (@count)', array('@count' => count($failed_methods))),

These counts are not really comparable. I wonder whether it would be better to show e.g. “Classes with failing tests (3 classes)” and “Methods with failing tests (4 methods in 3 classes)”. In fact I think the current wording is rather confusing, because it is not obvious what the numbers refer to.

sun’s picture

I actually played with the idea of just doing the change to DrupalTestCase::run(). That is, because most often, I don't even want to run other test methods in the first place; i.e., for the initial test run already. So I'm currently considering to implement some AJAX goodness to retrieve individual test methods of a test class on the initial test selection form already.... possibly for Devel module.

sun’s picture

Status: Needs work » Needs review
Issue tags: -DX (Developer Experience)
StatusFileSize
new1.62 KB

I think this is too much for D7, so we should just allow an advanced SimpleTest UI in contrib to run selected methods (without having to entirely replace SimpleTest module and/or DrupalWebTestCase -- if that is possible at all).

sun’s picture

Title: Allow to re-run only test methods having failures » Allow to run only certain test methods

Proper title for the much more focused goal.

The idea is that Devel or some other module in contrib is able to expose a different UI for running tests, allowing to not only select entire test cases to run, but more granularly select, which test methods in a test case should be run. Most often, you are only interested in one or two, but not any other method.

webchick’s picture

Interesting.

This looks like a low-impact change that could bring a lot of benefits and help with spreading TDD in Drupal. Agreed with not changing around the UI at this stage.

aspilicious’s picture

when retesting it could be that other changes in core affected several other testcases. So you cannot ensure you covered everything just by doing a retest on the test that failed previously.
(for example when there is to much time between a test and a retest)

You have to take care of that too.

sun’s picture

@aspilicious: Sure, you (or the testbot) can still run entire test cases or all tests. However, I most often know what I'm doing, so I have zero need for running tests that have nothing to do with the changes I'm performing.

sun’s picture

sun’s picture

Issue tags: +API change
StatusFileSize
new1.69 KB

Added phpDoc. This change cannot be really tested without implementing the functionality to run only certain methods in core. Thus, I think that this patch is ready to fly.

sun’s picture

Any feedback?

As mentioned before, this change cannot really be tested, as that would imply to do what it's intended for in Drupal core. :P

c960657’s picture

Status: Needs review » Reviewed & tested by the community

I tested this by hardcoding some arguments for run().

dries’s picture

Might be good to provide an example of how this is supposed to be used when writing tests.

I doubt this is easier than commenting out some test functions but maybe I fail to see the use case.

Let's be more explicit about how this improves our lives.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

Sounds like Dries's comment can be summarized as "needs more documentation", thus needs work.

sun’s picture

Status: Needs work » Reviewed & tested by the community

Quoting myself:

The idea is that Devel or some other module in contrib is able to expose a different UI for running tests, allowing to not only select entire test cases to run, but more granularly select, which test methods in a test case should be run. Most often, you are only interested in one or two, but not any other method.
...
we should just allow an advanced SimpleTest UI in contrib to run selected methods (without having to entirely replace SimpleTest module and/or DrupalWebTestCase -- if that is possible at all).

To summarize:

  1. This patch does not improve anything on its own.
  2. It merely allows to run only certain test methods instead of all.
  3. Since all test cases in core and contrib are extending the DrupalWebTestCase class and PHP OOP does not allow anyone to override individual class methods, there is no way to write a contributed module as replacement for SimpleTest module that would allow to run certain test methods only.
  4. This patch allows such a module to exist in order to expose an advanced testing UI to select the individual test methods to run.
  5. No improvement without that module. But without this patch, that module cannot exist. Typical chicken-n-egg problem.

For that sake, reverting to RTBC.

moshe weitzman’s picture

I've just committed a test-run command to drush and at sun's suggestion, I've added support for this fine new parameter. So, we now have our use case committed and value has been proven IMO. Agree with RTBC.

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -API change +API addition

I think a module that exposed a UI for this would be a complete and absolute nightmare, but the drush application has quite a few uses. Someone could set up their own "testbot lite" that just runs the most critical test cases for the major business logic of their Drupal site. Or even for run-of-the-mill core developers, to just hit up + drush test FooWhateverKeepsBreakingTestCase as they're drilling into a patch.

However, the "needs documentation" issue in #12/#13 still hasn't been addressed. In other words, there are details in this issue that aren't remotely hinted at in the code. Let's get some "why" stuff in there. Maybe something like:

+   * @param $methods
+   *   (optional) A list of class method names to run in the form of XXXXXXXX. By default, all methods
+   *   of the class are taken into account, but it can be useful to call only one
or a few test cases at a time for debugging purposes.

Note that only methods starting with
+   *   "test" are executed.

(Obviously, with the formatting vastly cleaned up :P)

And this seems more like an API addition than an API change; there's nothing existing test authors need to adjust.

sun’s picture

Status: Needs work » Needs review
StatusFileSize
new1.89 KB

Alright, incorporated the suggestion in #16.

klausi’s picture

StatusFileSize
new1.7 KB

Fixed a typo ("unless a specific list" instead of "unless as specific list")

dries’s picture

Status: Needs review » Fixed

OK, the extra documentation is helpful. Committed to CVS HEAD.

Status: Fixed » Closed (fixed)
Issue tags: -API addition

Automatically closed -- issue fixed for 2 weeks with no activity.