The mod_setenvif module allows you to set environment variables according to whether different aspects of the request match regular expressions you specify.
I’ve never claimed to be a server guru, and I’ve never had much interest in delving into Apache configuration files, but web programming almost request that I dig down and learn about what I’m using in order to make the best use of the technologies I’m using. Besides, I’m well past the point where I can keep making excuses for not learning Apache.
Zend Framework 1.10 uses the .htaccess file to set the enviromental variable APPLICATION_ENV. It does this using SetEnv.
SetEnv APPLICATION_ENV production
This let’s us set the environment to production or development, obviously. The idea is that you can set the variable depending on where the files are: a production server or a development server.
However, I wanted something a bit simpler at the moment. I wanted to the variable based on the URL used. beta.example.com would get the development site, and www.example.com would load up the production site. Both sites share the same directory as their web directory, but I want the live site to display a ‘Coming soon…” message, while the beta site would let me work. I’m not concerned with people getting access to beta, and the only difference will be the display of the default page, but it’s a simple thing. Now, I could have done this in PHP, but I didn’t want to do this. At the same time, I had in mind the ability to use this setting of environmental variables something I could use for other things, like debugging, web services, and what not. Being able to let Apache handle this, and then letting Zend build the configuration based on this setting, would let me not worry about programing any of this logic into my system. I just program away, and I can make the assumption that whatever happens based on the URL will happen appropriately.
Anyways, a quick check of the docs for SetEnv lead me to discover SetEnvIf. I’ve seen this before, but I never paid much attention to this setting. It’s rather simple, and could be very powerful.
As a simple example, I want to set the APPLICATION_ENV variable to production if the website is www.example.com, and development if the site is beta.example.com. This worked:
That was the initial code. Of course, after reading through the manual, I read about SetEnvIfNoCase, which is the same as SetEnvIf, except the “matching is performed in a case-insensitive manner.”
One problem I have with the two big TDD sets out there for PHP (SimpleTest and PHPUnit) was the incompatibility of working in the setup I am working in. SimpleTest apparently wanted to take over error control, something my environment was already handling, and PHPUnit didn’t have a web interface by default. Finally, both wanted to do things their way. None of this is bad, but working in a shop were Unit Testing isn’t the norm at the moment (though momentum exists for the change to take place), I didn’t have time to play around with getting them setup properly. But I wanted to test.
So I did what any programmer would do in my place: I started building my own simple testing sweet. Testing doesn’t have to be complicated. It doesn’t have to involved massive amounts of setup and tear down. In reality, at the very heart of it, just getting some form of tests started is part of the path toward redemption.
My current testing platform is very, very simple. It consists of a file that displays all the tests available to run in a directory (or packages of tests in sub-directories of the main test folder). You click a link and it runs the appropriate test. It then prints out a simple page that shows the number of successful tests.
The basic testing screen gives me immediate, important feedback: Did the tests succeed? Did the tests fail?
Here is a completed testing screen. As we can see, it ran the test, and seven tests failed, and four passed fine. We can review the test below inside the testing screen, saving us even more time. But all this is fairly useless beyond that. We know quickly that the test failed. Now we have to fix those tests. This gives us a list of things we have to fix, a ‘todo’ list of things that need to be addressed. But, what exactly do we need to fix?
We can click on the text right above the test results and it will give us this information.
Clicking the text right above the testing results expands the result view to show all the tests run, and their results. Errors first, as they are the most important.
Now you can see where the fun comes in. Clicking the text expands the details (using jQuery), and now we can see all tests that failed and passed, where they are by line number, and what they received in testing, and what they expected, as well as why the test failed. We can now trace the errors to each line of code, so we know exactly what code caused this to fail, or more precisely, what test failed. The same works for the tests that passed. Of course, even this isn’t as efficient as it could be. Granted, this provides us with enough information to work with, and in some cases, it’s all the information you need. Information overload is something I wanted to avoid. I don’t need to see more than this, except sometimes I do.
This is where we start to really dig deep. We can now view each test, where it ran in the testing script, what it expected, what it got, and it even shows the code used to perform the test so their is no confusion.
Clicking on the top Failed or Passed boxes will expand all the associated tests to further details (again, using jQuery). We can also click on tests to open them up one by one, allowing us to view only what we want. This lets us see what the offending code was that caused the failure without having to go and look for it. This is most useful when we have an unexpected error.
Closeup of a detailed test
Getting to this point is quick and easy. Drilling down doesn’t require any real effort, and we review things as we go along. We see the failures, we open them, and we allow ourselves the opportunity to review all the errors without forcing ourselves to become overcome with too much information. We can focus on what we need to work on at the moment.
Finally, at the top of the page, the name of the test is also set to rerun the test. This is done on purpose because this testing page sits inside a frame. I use the frame as a type of bookmark for in-house development tools and sites, frequently used links that I don’t want to put in any one browser. After all, I’m generally working inside Firefox, IE, Chrome, and Safari, usually at least two of the four.
There are some problems with my setup. The packaging of tests is really dirty at the moment. Every tests needs to exist in a certain directory. Each tests also needs to start with ‘test_’, and a name like ‘test_AlwaysFail.php’ turns into ‘AlwaysFail.’ ‘test_Always_fail.php’ would be run as the test ‘Always fail.’ But this also means each test file is self-contained, and considered on test. I’ve setup a way to run all the tests at once, but it’s cumbersome, and doesn’t work like it should: quickly, easily, and efficiently.
I also need a way for tests to better document themselves, and a way to automate this feature.
Tests also run when you click on the initial testing link. While this makes testing easy, testing isn’t always about just running the test. There should be someway for me to allow for a launcher page, a way to go to the test page and let me do something if I want, even if it’s as simple as reviewing the tests that will run.
I should be able to run multiple test pages together in a certain order. Setting up a test is important, but I want to test that setup, as usually it’s using the tools I want to test in the first place to do the setup. At the same time, I want setting up test requirements to be easy. This is where the above idea of having a launcher page might be best. Allow me to go through a series of tests step by step, or all at once.
The general theme here is focusing on using tests as development tools, not just as error checking devices. Of course, being able to run all the tests and get an easy to use report is critical.
I don’t imagine for a second my testing platform is as mature as any of the other ones out there now. However, I didn’t start out with the intent of building one. I just needed a simple way to run tests. Then I needed a way to report tests. As time dragged on, I would add one feature, and then another, and keep adding as I needed them. I didn’t spend time developing this, it just evolved.
This all isn’t to suggest that SimpleTest or PHPUnit are bad. I’m using them as a reference for some of the ideas I’m having. But I always focus on how to take what they do, and make it fit with what I want.
I’ve tried multiple times to restart blogging. I’ve blogged before. The site was newbienetwork.net, and then became phpcomplete.com. Both were fun, new, exciting, and interesting. I was learning to program, learning PHP, and teaching others along the way.
Of course now I’m old and jaded. I’ve been programming for 10 years now, and I’ve been focused on credit card processing for the past 8 years. Specifically, I’ve been focused on credit card processing for the adult industry. 8 years of doing that, in an industry that makes it a challenge as well as interesting. Don’t get me wrong. I love what I do. I find everything I’m involved with to be a challenge. There is a lot more that goes into it then people think. However, I also want to break free.
At least on a personal programming level. PHP programming for so long means I know what I’m doing. I have an easy grasp of PHP. I understand how it works, I understand web development as a whole. I know it well enough that I feel comfortable with it. The problem is, I need to branch out.
Of course, the question is, what do I branch out into? I’ve dabbled with game programming using C# and XNA. This has been a recent bit of fun. I’ve wanted to try Java, but frankly, Java is filled with so many options its rather daunting. Where do I start? Maybe the same place I started with C#? A book! But then why not get back into C++. I’ve done C++ early on, but I stopped when PHP became my focus. I could get back into it, but all this is beside the point.
What would I create? More importantly, why build it in any of these languages? So much is web-focused these days that in many ways, it’s worthwhile to learn the new things coming out for the web. Become more fluent with JavaScript, CSS3, and HTML5. Canvas looks amazing. There is so much room for growth. Seeing what people are creating online makes me wonder why I should worry so much about programming offline.
Consider that I am busy learning Zend and Doctrine. Now, I know them well enough I can work with them, but frankly, I don’t consider myself as knowing something until I can avoid using the documentation and I just hammer out code. Both Zend and Doctrine are big, monstrous pieces of code and each have lots of options, do lots of things. Granted, I don’t think I’ll ever really learn every aspect of Zend. Lots of packages, lots of tools I don’t need every day. But there are also a large number of things Zend does that I should learn.
Of course, after I think about all that, I think about what else I am learning. I’ve been pushing myself to use TDD every day, in everything I program. Constant Integration, Agile development, documentation, version control. So much going on every day, so many new things happening.
In the old days, you got a website, you put up a simple page with SSI header and footer, and you were happy. You copied a Perl script, dumped it into cgi-bin, hoped it worked and didn’t throw up a 500 error, and that was your web page.
Oh the old days. I miss, but frankly, these days are a lot more fun.