Writing complex "helper" methods into testcases?

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

Post Reply
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Writing complex "helper" methods into testcases?

Post by Chris Corbyn »

I'm at a point where I think I need to seriously refactor a few of my testcases because they repeatedly use long, complicated regexes like this:

Code: Select all

public function testDetachingALLPartsFromAnEmailWithAnAttachmentResultsInCorrectStructure()
	{
		$msg = new Swift_Message();
		$id1 = $msg->attach(new Swift_Message_Part("some part"));
		$id2 = $msg->attach(new Swift_Message_Part("another part"));
		$id3 = $msg->attach(new Swift_Message_Attachment("foobar"));
		$id4 = $msg->attach(new Swift_Message_Attachment("zipbutton"));
		
		$msg->detach($id2);
		$structure = $msg->build()->readFull();
		//$this->dump($structure);
		$this->assertPattern(
			"~.*?Content-Type: multipart/mixed;\\s* boundary=(\"?)(.*?)\\1\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\2\r\n" .
			"Content-Type: multipart/alternative;\\s* boundary=(\"?)(.*?)\\3\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\4\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\4--" .
			"\\s*\r\n--\\2\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\2\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\2--~s",
			$structure);
		
		$msg->detach($id1);
		$structure = $msg->build()->readFull();
		//$this->dump($structure);
		$this->assertNoPattern("~Content-Type: multipart/alternative~", $structure);
		$this->assertNoPattern(
			"~.*?Content-Type: multipart/mixed;\\s* boundary=(\"?)(.*?)\\1\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\2\r\n" .
			"Content-Type: multipart/alternative;.*?\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\2\r\n" .
			".*?\r\n\r\n" .
			".*?\r\n--\\2--~s",
			$structure);
	}
The regex are:

a) A vital annoyance to test what I need
b) COMPLICATED!!

I'd like to simplify, and make the tests more readable to "Average Joe" by allowing something like XML or a native multi-dimensional array to generate those regex, but that's complicated in itself so I'd then need to add a handful of methods which tests the helper functions of my test case before I ever use the helper functions. Does this seem reasonable or am I just adding to the risk of over-complicating things?

I haven't even begun to pull hairs out thinking about actually creating those regex in a flexible fashion 8O
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

I think that even though it is a lot, it is the "simplest" way to test. You are providing test data, and asking for test results.

If you start to build dynamics into your tests, you'll need to test your object/function which creates the dynamic content. Kind of like the dependency tree which you break with mock's, only this time you break with static data. :)
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

I think the rock is better than the hard place ;).

Are the regex's going to change in the future? If not, there's little point messing with them since they are specific to a test case. Now, that method name on the other hand...
testDetachingALLPartsFromAnEmailWithAnAttachmentResultsInCorrectStructure()
:P
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Maugrim_The_Reaper wrote:I think the rock is better than the hard place ;).

Are the regex's going to change in the future? If not, there's little point messing with them since they are specific to a test case. Now, that method name on the other hand...
testDetachingALLPartsFromAnEmailWithAnAttachmentResultsInCorrectStructure()
:P
"CorrectStructure" needs describing a little better. I think it should be:

Code: Select all

public function testDetachingAllAlternativePartsFromAMultipartMixedAndAlternativeEmailYieldsNoMultipartAlternativePartInBody()
{
    //
}
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Can you not split that test up? I realise you are testing a whole email (thus one test) with 'x', 'y' and 'z' but would it be better to test 'x', 'y' and 'z' seperately? A group maybe?
User avatar
dreamscape
Forum Commoner
Posts: 87
Joined: Wed Jun 08, 2005 10:06 am
Contact:

Post by dreamscape »

d11wtq wrote:

Code: Select all

public function testDetachingAllAlternativePartsFromAMultipartMixedAndAlternativeEmailYieldsNoMultipartAlternativePartInBody()
{
    //
}
Good grief charley brown... 8O .. yuk... :D

I like to group test cases by context, so maybe:

Code: Select all

class A_Multipart_Mixed_And_Alternative_Email extends Test_Case
{
	public function test_Detaching_All_Alternative_Parts_Yields_No_Multipart_Alternative_Part_In_Body()
	{
	}	
}
And actually that test would be changing context in the middle of the test, so even better would be:

Code: Select all

class A_Multipart_Mixed_And_Alternative_Email_With_All_Alternative_Parts_Detatched extends Test_Case
{
	public function test_Has_No_Multipart_Alternative_Part_In_Body()
	{	
	}
}
Much easier to digest... JIMHO :wink:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

True :) I've never tried it, but I assume simpletest can run Group tests inside group tests.

I'm actually going to go through my tests this weekend and refactor/tidy up a bit, possibly even add descriptive comments to the files for some if the scarier tests.
Post Reply