Posted on

Second sprint as PHPUnit tester: Learning Fixtures and YAML

Since I’ve been building my knowledge base as a unit tester here, and showing that I am capable at it, I’ve been stuck with even more testing responsibilities.

The new tests are far more complex, and will require that I feed our system certain sets of data, in order to create the post conditions.

This most likely means generating fixtures and using YAML format files.
Although CIUnit has a “php generate fixtures” command which I can execute, this only dumps the format of the database, and “manual labor” is required to setup the data.

As I metioned before, I dont like having to sit, and click all day just to get something basic going. So I am looking for an automated solution, since I would like to use my entire dataset, and be able to quickly experiment and switch between them. Data entry is not an option.

Export the data into yaml files though, has proven to be a headache. Most posts on the interwebs seem to point to using Doctrine CLI or ORM-Designer as the correct tool of choice for solving this problem.

First I tried to use command line based solution in XAMP 3.1.0 by installing doctrine using pear.
But I had a rough weekend, and my brain is not able to process how to actually use the Doctrine CLI to export the data to YAML files.

So at the current moment I am trying out ORM-Designer. The application just explodes in my face with all kinds of options I don’t care about at all. I am not trying to design a project, or do anything but export the existing data into YAML!

I realized that when something is not on the interwebs, that means its because its right under my nose, and that I am being foolish for not finding it. (very rough weekend).

Loading phpMyAdmin, and going to export the table I found the grail I was looking for! phpMyAdmin is capable of exporting into YAML! Great, now lets see if I can get my tests working with these fixtures.

 

 

Posted on

Down time and charging clients

I don’t know.

I hate days when you don’t have a lot of work. Or you hit a blocker.

Its like. You just started, you don’t have much to do, and what, do you not charge for a full day?

Do you hang around shooting the breeze until the clock hits the right position?

Do you go home and charge anyway, knowing you will make up for it later?

Awkward.

 

At first, when I was younger, I was so careful about my arrival and departure time.

But then, after seeing how difficult this industry is, with all these head hunters, and how hard the contracts are, with all the stress experienced.

I’ve decided, I will charge a full day every time.

If you hired me, you should employe me. For me the time sheet is just another invoice.

I’m self incorporated and the cost of doing business is high. Not to mention there is mark up on my rate by the agency, so I am not making as much as you think cause they always fight to increase their own profit margins.

Gotta learn how to cut out the middle-man, and get hired with big companies directly.

Then I would just have to send one invoice, it would be less awkward, and I would make more money too.

 

 

Posted on

Shout out to Mike Funk and Andrej Farkas

 

Its so amazing when programmers, that you have never met in person before, reach out to you and help you out, when you need it!

I just want to say thank you to these guys:

Mike Funk
Andrej Farkas

They are both active CI community members.
Although, Andrej has said he now uses a more ‘Romanian’ framework, and he has ditched CI behind.

I guess it must be very frustrating coding in a foreign language. I mean, there is this joke about a Russian programmer who learned English in a couple of months, and when asked “How did you do that?”, his response was “Its easy, its just like C++!”.

Andrej  has interesting articles about Laziness being good for OOP design, and about writing unit tests first.

 

 

Anyways, thanks again guys!

Posted on

Reverse Engineering CodeIgniter, Sparks, to get CIUnit working

I ran into more issues with the spark for  cURL and the spark for Rest.
These are two awesome contributions by Phil Sturgeon to the CodeIgniter family.

Honestly this technology platform is way behind.  Node JS seems better equipped to manage packages with npm and nvm. And why do we have PEAR, PHAR, and Composer and a framework specific SPARK.  We are seeing the tower of babel problem when it comes PHP frameworks. Too many, too fast, the community has not congealed behind a single choice.
So developers from a huge PHP base are ending up being spread thin, some contributing to Yii, some on CodeIgniter, some on Laravel.

See if the programmers who made one of the other frameworks had worked as contributors to CodeIgniter, I probably would already have better CIUnit integration.

Anyway, so the problem was that the AutoLoader for PHPUnit command line execution of the project was being used twice! And somewhere in the first process, the sparks were added to an Array instance used to keep track of which sparks had been loaded.

Removing this, ‘duplicity’ check, made the application fail, because we were loading CURL twice. 1.2.0 spark and 1.2.1 spark were both being loaded and failing. So when I removed the duplicate CURL spark, the PHPUnit tests started to fly!

So I just put a CLI check in the function that removed duplications, in My_Loader.php:

# If we’ve already loaded this spark, bail
if(array_key_exists($spark_slug, $this->_ci_loaded_sparks)) {
if( php_sapi_name() != ‘cli’ )
return true;
}

 

This way, if and only if I am executing this CodeIgniter project on the command line, will sparks be loaded freely.

Posted on

Ubuntu Samba Torture

I recently did an update on my home network file server, and of course samba stopped working. 2 hours wasted already trying to fix it. The problem is in the GUI the samba config program never actually executes, just closes silently failing.

And when I try it on the command line, I get this goodness:

# gksu system-config-samba
Traceback (most recent call last):
File “/usr/sbin/system-config-samba”, line 45, in <module>
mainWindow.MainWindow(debug_flag)
File “/usr/share/system-config-samba/mainWindow.py”, line 116, in __init__
self.samba_user_data = sambaUserData.SambaUserData(self)
File “/usr/share/system-config-samba/sambaUserData.py”, line 46, in __init__
self.readSmbPasswords()
File “/usr/share/system-config-samba/sambaUserData.py”, line 56, in readSmbPasswords
if string.strip(line)[0] != “#”:

____________

This sucks so bad. But its not too bad, cause I have nothing mission critical on that file server anyway.
Honestly I was just experimenting with Ubuntu / Samba and using that fileserver for entertainment / media storage.
I am getting another box soon for Windows, we’ll try out SMB there too.

 

 

 

Posted on

I love these guys! Phil Sturgeon & Kenji Suzuki!

“I release code by the metric fuckton, I work on PyroCMS, Pancake, FuelPHP & CodeIgniter and I occasionally get chased by bears.” – Phil. Him I just like cause he curses as much as I do. Also one of my co-workers told me that Phil accepts donations in the form of drinks from his local pub. Has a button that puts money on his tab! Totally believe this cause there are pictures of Phil downing dark beer on the net.

I’ve been looking at Bonfire, CIUnit, CodeIgniter. Sitting around shooting the breeze with my co-workers. When Phil’s name came up as an open source contributor.

And thanks to another Open Source contributor, I Finally found a good source for integrating CodeIgniter 2.1 with PHPUnit
http://blog.famakinwa.net/content/getting-codeigniter-phpunit-and-jenkins-working-together

And I have been able to get the basic model and controller tests to work, so now its just a matter of writing a real world test for the CI project and hoping everything doesn’t fall apart.

Quick note to Phil, stop drinking dark beer, it gives you hangovers.
And Kenji, much love to you my main man from japan.
http://d.hatena.ne.jp/Kenji_s/20120117/1326763908

Its all thanks to you keeping CIUnit up to date and being like, the ONLY active open source developer who is interesting in PHPUnit and Unit testing with CI.
Now a drink for you, I shall buy.

Posted on

PHPUnit CodeIgniter FAIL

Well today was a horrible waste of time. All thanks to our good friends at CIUnit / CodeIgniter.
Seems that PHPUnit and CodeIgniter to not integrate out of the box.
And CIUnit, at the time of this writing, trying out the fooStack, is for version 1.7 of CI, whilst we are using 2.1. So that didn’t work.

And this video below demonstrates wiring the two ‘frameworks’ together. As you can see there is a lot of work, manual work, which I don’t do anymore since I learned Grails (cause it does the work for you). Like using your eyes to identify dependencies and rewriting them with fake stubs. Such a f*ing headache just to be able to assert that 1 = 1.

 

Posted on

Perforce vs SVN

Perfoce I miss you. I am back in the hands of my old version control system, SVN. TurtoiseSVN on Windows XP to be precise.
If anything SVN easier to use, although I do miss the GUI and structure of Perforce.

Posted on

Functional Unit tests and more?

Okay,

So I got my Selenium PHPUnit integration working great, and that’s something I can even integrate into a build process.
Super easy, cause I don’t have to do anything but scan the DOM for whats expected.

See, the difficulty of doing it the PHPUnit / CI way is that you loose either the tight integration with CI or with the build tool.

If I used Unit_Test, a library in the CI framework, I could verify the code is functional, but its not really a test suite designed for build time. At least I haven’t seen an example yet. Yes, lots of questions indeed. Like this great question about how would someone go about implementing the CI Unit_Test class in a best practice way:
http://codeigniter.com/forums/viewthread/172956/
That doesn’t seem like it integrates with a build process very easily.

And the problem with PHPUnit is that we can only test core logic, or libraries, and not really the controllers. Its great for controllers that return values, like json objects. But what about methods that wire in the view and layout and actually render the page. I don’t yet know h0w to test those. I think I saw a library for PHPUnit that will do the job, CIUnit. But I am not sure, even, how you would wire all that together. There are a lot of CIUnit forks out there on bitbucket, but it doesn’t seem like a  very mature project, still, seems chaotic.

And then another question is, is it how much testing is really necessary? 100% code coverage? I mean, isn’t functional testing with selenium enough?
Maybe just a few core tests with PHPUnit also, for whatever you can share from the CI project.

Posted on

Important Selenium Methods


Selenium RC API: Setup

Method Meaning
void setBrowser(string $browser) Set the browser to be used by the Selenium RC server.
void setBrowserUrl(string $browserUrl) Set the base URL for the tests.
void setHost(string $host) Set the hostname for the connection to the Selenium RC server.
void setPort(int $port) Set the port for the connection to the Selenium RC server.
void setTimeout(int $timeout) Set the timeout for the connection to the Selenium RC server.

 

Selenium RC API: Actions

Method Meaning
string start() Run the browser and set session id.
string stop() Close the browser and set session to NULL.
string open(string $url) Open the URL.
string close() Simulates the user clicking the “close” button in the titlebar of a popup window or tab.
string goBack() Simulates clicking on the browser’s “go back” button.
string refresh() Simulates clicking on the browser’s “refresh” button.
string click(string $locator) Clicks on a link, button, checkbox or radio button. If the click action causes a new page to load, call waitForPageToLoad().
string clickAndWait(string $locator) Clicks on a link, button, checkbox or radio button. Calls waitForPageToLoad().
string fireEvent(string $locator, string $eventName) Simulate an event to trigger the corresponding “onEvent” handler.
string keyDown(string $locator, string $keycode) Simulates a user pressing and holding a key.
string keyPress(string $locator, string $keycode) Simulates a user pressing and releasing a key.
string keyUp(string $locator, string $keycode) Simulates a user releasing a key.
string mouseDown(string $locator) Simulates a user pressing and holding the mouse button on the specified element.
string mouseOver(string $locator) Simulates a user hovering a mouse over the specified element.
string check(string $locator) Check a toggle-button (checkbox/radio).
string uncheck(string $locator) Uncheck a toggle-button (checkbox/radio).
string addSelection(string $locator, string $optionLocator) Add a selection to the set of selected options in a multi-select element using an option locator.
string removeSelection(string $locator, string $optionLocator) Remove a selection to the set of selected options in a multi-select element using an option locator.
string select(string $selectLocator, string $optionLocator) Select an option from a drop-down using an option locator.
string submit(string $locator) Submit the specified form.
string type(string $locator, string $value) Type into an input field.
string selectWindow(string $windowId) Selects a popup window; once a popup window has been selected, all commands go to that window. To select the main window again, use “null” as the target.
string setContext(string $context, string $logLevelThreshold) Writes a message to the status bar and adds a note to the browser-side log.
string answerOnNextPrompt(string $answer) Instructs Selenium to return the specified answer string in response to the next JavaScript prompt (window.prompt()).
string chooseCancelOnNextConfirmation() By default, Selenium’s overridden window.confirm() function will return TRUE, as if the user had manually clicked OK. After running this command, the next call to confirm() will return FALSE, as if the user had clicked Cancel.
string waitForCondition(string $script[, int $timeout]) Runs the specified JavaScript snippet repeatedly until it evaluates to TRUE.
string waitForPageToLoad([int $timeout]) Waits for a new page to load.
string waitForPopUp(string $windowId[, int $timeout]) Wait for a popup window to appear and load up.

 

Selenium RC API: Queries

Method Meaning
string getAlert() Retrieves the message of a JavaScript alert generated during the previous action.
array getAllButtons() Returns the IDs of all buttons on the page.
array getAllFields() Returns the IDs of all input fields on the page.
array getAllLinks() Returns the IDs of all links on the page.
string getBodyText() Returns the entire text of the page.
string getConfirmation() Returns the message of a JavaScript confirmation dialog generated during the previous action.
int getCursorPosition(string $locator) Returns the text cursor position in the given input element or textarea.
void setCursorPosition(string $locator, int $position) Moves the text cursor to the specified position in the given input element or textarea.
string getElementAttribute(string $attributeLocator) Returns the value of an element attribute.
string getEval(string $script) Returns the result of evaluating the specified JavaScript snippet.
string getExpression(string $expression) Returns the specified expression.
string getHtmlSource() Returns the entire HTML source between the opening and closing “html” tags.
string getLocation() Returns the absolute URL of the current page.
string getPrompt() Returns the message of a JavaScript question prompt dialog generated during the previous action.
string getSelectedId(string $selectLocator) Returns option element ID for selected option in the specified select element.
array getSelectedIds(string $selectLocator) Returns all option element IDs for selected options in the specified select or multi-select element.
string getSelectedIndex(string $selectLocator) Returns option index (option number, starting at 0) for selected option in the specified select element.
array getSelectedIndexes(string $selectLocator) Returns all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element.
string getSelectedLabel(string $selectLocator) Returns all option labels (visible text) for selected options in the specified select element.
array getSelectedLabels(string $selectLocator) Returns all option labels (visible text) for selected options in the specified select or multi-select element.
string getSelectedValue(string $selectLocator) Returns option value (value attribute) for selected option in the specified select element.
array getSelectedValues(string $selectLocator) Returns all option values (value attributes) for selected options in the specified select or multi-select element.
array getSelectOptions(string $selectLocator) Returns all option labels in the specified select drop-down.
string getTable(string $tableCellAddress) Returns the text from a cell of a table.
string getText(string $locator) Returns the text of an element.
string getTitle() Returns the title of the current page.
string getValue(string $locator) Returns the (whitespace-trimmed) value of an input field (or anything else with a value parameter).
boolean isAlertPresent() Determines whether an alert occured.
boolean isChecked($locator) Determines whether a toggle-button (checkbox/radio) is checked.
boolean isConfirmationPresent() Determines whether confirm() has been called.
boolean isEditable($locator) Determines whether the specified input element is editable.
boolean isElementPresent($locator) Determines whether the specified element is somewhere on the page.
boolean isPromptPresent() Determines whether a prompt is present.
boolean isSomethingSelected(string $selectLocator) Determines whether some option in a drop-down menu is selected.
boolean isTextPresent(string $pattern) Determines whether the specified text pattern appears somewhere on the rendered page shown to the user.
boolean isVisible($locator) Determines if the specified element is visible.

 

Assertions

Assertion Meaning
void assertAlertPresent() Reports an error if no alert is present.
void assertNoAlertPresent() Reports an error if an alert is present.
void assertChecked(string $locator) Reports an error if the element identified by $locator is not checked.
void assertNotChecked(string $locator) Reports an error if the element identified by $locator is checked.
void assertConfirmationPresent() Reports an error if no confirmation is present.
void assertNoConfirmationPresent() Reports an error if a confirmation is present.
void assertEditable(string $locator) Reports an error if the element identified by $locator is not editable.
void assertNotEditable(string $locator) Reports an error if the element identified by $locator is editable.
void assertElementValueEquals(string $locator, string $text) Reports an error if the value of the element identified by $locator is not equal to the given $text.
void assertElementValueNotEquals(string $locator, string $text) Reports an error if the value of the element identified by $locator is equal to the given $text.
void assertElementContainsText(string $locator, string $text) Reports an error if the element identified by $locator does not contain the given $text.
void assertElementNotContainsText(string $locator, string $text) Reports an error if the element identified by $locator contains the given $text.
void assertElementPresent(string $locator) Reports an error if the element identified by $locator is not present.
void assertElementNotPresent(string $locator) Reports an error if the element identified by $locator is present.
void assertLocationEquals(string $location) Reports an error if the current location is not equal to the given $location.
void assertLocationNotEquals(string $location) Reports an error if the current location is equal to the given $location.
void assertPromptPresent() Reports an error if no prompt is present.
void assertNoPromptPresent() Reports an error if a prompt is present.
void assertSomethingSelected(string $selectLocator) Reports an error if the option identified by $selectLocator is not selected.
void assertNothingSelected(string $selectLocator) Reports an error if the option identified by $selectLocator is selected.
void assertTextPresent(string $pattern) Reports an error if the given $pattern is not present.
void assertTextNotPresent(string $pattern) Reports an error if the given $pattern is present.
void assertTitleEquals(string $title) Reports an error if the current title is not equal to the given $title.
void assertTitleNotEquals(string $title) Reports an error if the current title is equal to the given $title.
void assertVisible(string $locator) Reports an error if the element identified by $locator is not visible.
void assertNotVisible(string $locator) Reports an error if the element identified by $locator is visible.