Getting Started with BDD testing and TestBox

I have transferred this message from one I sent to Brad. Sorry, I am still finding my feet with Slack…

So, when I go to my test template with:

<cfset r = new testbox.system.TestBox("com.bddTests.BDDTest1")> 
<cfoutput>#r.run()#</cfoutput>

I get the following error:

Object of type class coldfusion.runtime.Struct cannot be used as an array
 
The error occurred in C:/Users/Charles Robertson/Documents/commandbox-jre-win64-4.7.0/testbox/system/reports/assets/simple.cfm: line 518
Called from C:/Users/Charles Robertson/Documents/commandbox-jre-win64-4.7.0/testbox/system/reports/assets/simple.cfm: line 244
Called from C:/Users/Charles Robertson/Documents/commandbox-jre-win64-4.7.0/testbox/system/reports/SimpleReporter.cfc: line 53
Called from C:/Users/Charles Robertson/Documents/commandbox-jre-win64-4.7.0/testbox/system/TestBox.cfc: line 415
Called from C:/Users/Charles Robertson/Documents/commandbox-jre-win64-4.7.0/testbox/system/TestBox.cfc: line 164
Called from C:/ColdFusion11/cfusion/wwwroot/nationallottery/bdd-test/index.cfm: line 3
516 : 							<cfif structKeyExists( local.thisSpec, "message" )>
517 : 								<div>
518 : 									<cfif arrayLen( local.thisSpec.failOrigin )>
519 : 										<div><pre>#local.thisSpec.failOrigin[ 1 ].raw_trace#</pre></div>
520 : 										<div class="pl-5 mb-2 bg-light">

BDDTest1.cfc:

<cfscript>

  component {
  
	// executes before all suites 
	
	function beforeAll() {
	}
	
	// executes after all suites
	
	function afterAll() {
	}
	
	// All suites go in here
	 
	function run() {
	  describe("A suite", function() {  
		it("contains spec with an awesome expectation",       
		  function() {   
			expect( true ).toBeTrue();  
		  }
		);  
		it("contains a spec with more than 1 expectation",       
		  function() {   
			expect( [1,2,3] ).toBeArray();   
			expect( [1,2,3] ).toHaveLength( 3 );  
		  }
		); 
	  }); 
	} 
  
  }

</cfscript>

Holy cow, this exciting.

I had a peak in some of the test samples that TestBox provide and kept seeing:

component extends="testbox.system.BaseSpec"

In the Component head.

Tried out in my CFC and voila, all is good!

My first BDD test. Don’t really know what it all means, but it feels good to have the framework working!

Now what I would really like to know is how I would test a conditional statement in a CFM template?

I mean how do I link a BDD test to the templates in my website. I know the sample tests are just examples, but I have yet to see a test that actually tests anything in the real world.

Lets say I have a statement, in one of my templates like:

<cfif temperature GT 100>
I am boiling
<cfelse>
I am still alive
</cfif>

How do I create a test to test the second branch of this conditional…

I just cannot see how I link these test CFCs to my code?

Or is the idea to recreate this conditional in the test CFC and then test it like that.

This seems to be like a hell of lot of extra work, if you had to create a test statement for every single conditional in a website’s codebase, especially considering that the codebase is likely to be refactored during its lifetime.

Why not just test the conditional statements in situ. If it throws an error, debug and test again, until the problem is fixed.

I am trying to see the rationale behind BDD testing?

Using _InternalRequest() you can link the external template. To execute the template based upon some conditions also, you have to pass the variable in some of the scopes like form, URL etc., Only the output content is passed to the component. Here below I demonstrate the test case,

//exeFile.cfc

component extends="testbox.system.BaseSpec"{
	function beforeAll(){
		variables.Dir = '#GetDirectoryFromPath(getCurrentTemplatePath())#desiredFolderName\';
	}
	function run( testResults , testBox ) {
		describe( "about the case", function() {
			it(title = "sample title 1", body = function( currentSpec ) {
				//function to link the template
				local.result = _InternalRequest(
					template:"#variables.Dir#/test.cfm",
					forms:{Scene=1}
				);
				expect(result from the external file).toBe(your expected result]);
			});
		});
	}
}

Inside the folder(desiredFolderName) you have the file test.cfm, In that file you have to place the code based upon your conditions,
//test.cfm

<cfparam name="form.scene" default="">
<cfscript>
if(form.scene EQ 1){
		//code to process
	}else if(form.scene EQ 2){
		//code to process
	}else if(form.scene EQ 3){
		//code to process
	}else{
		//code to process
	}
</cfscript>

You can get back the result from the template to the component as structure format. The key fileContent have the output for the request. For example, expect(local.result.filecontent.trim()).toBe(“test case executed”]);

Lucee repo contains lot of test cases that were executed on a test box, you can also able to refer here.

This is the URL, you can refer more about the testbox.

http://testbox.ortusbooks.com/primers/testbox-bdd-primer/bundles-group-your-tests
https://cfdocs.org/testbox

Thanks for this information. In fact, this is a great example of the point I was trying to get across.

That seems like a lot of extra code & time, to test something that could just be tested “in situ”.

I am trying to understand what the advantages are of BDD testing, over just testing the code in the template directly.

So with your example:

I could just:

  1. Submit the form

  2. If it throws an error, I could use the error message to fix the problem

Rather than creating a separate test CFC & test template, which is essentially duplicating the code.

I know developers are now expected to write these tests, but why?

Because It is very useful to check whether the latest changes will affect the behaviour of existing functionality or not. With the help of test cases, automatically checks all the functions & their expected result. No need to check it manually.

That sounds quite dangerous.

Presumably, you need to test the updated templates as well. And sometimes, you may also need to update the test cases as well, if certain template conditions have changed.

I wish I could see a demonstration of these benefits, with a real world example. Then, the penny might drop.

I am trying to understand this from a theoretical perspective. I have been thinking about this issue for many years, and, despite having seen many BDD examples, I have never seen one, that sells this paradigm, to me.

Thanks anyway for taking the time to explain this to me. I am sure you are right about this, because no one in their right mind would spend the extra time required to write these tests, unless they were of some benefit.

I just cannot “see” it, myself.