Friday, March 23, 2012

WordPress: PHP Is Not Installed

So I'm starting to work on a little project at home involving a website built in WordPress. This is all new to me so naturally, there are going to be bumps in the road. Anyway, I managed to install Apache, MySQL, and PHP. However, when attempting to install WordPress, I was continually presented with the error:
Error: PHP is not running
WordPress requires that your web server is running PHP. Your server does not have PHP installed, or PHP is turned off.
WHAT??? The PHP test file worked perfectly fine! I googled and googled some more trying to find a solution to this and while there question appeared frequently, there was never a good answer. I finally figured it out myself though!

The problem was in how I was accessing install.php. Through Windows Explorer, I had navigated to my WordPress directory and double clicked on readme.html. The file opened in Firefox. Then I clicked the hyperlink in Step 2 "wp-admin/install.php". This opened the file with the error, and here's the problem: look at the address bar:
file:///C:/apache/htdocs/wordpress/wp-admin/install.php
In order to make it work, you need to hit it from LOCALHOST
http://localhost/wordpress/wp-admin/install.php

BAM! Done! 

Environmental Variables:
OS: Windows XP SP3
Webserver: Apache 2.2
MySQL: 5.5.21
PHP: 5.2.17
WordPress 3.3.1

Friday, March 16, 2012

Gems of Wisdom from Fellow Software Testers

This past week, I've been feeling very cerebral and the timing couldn't have been better because I've been able give my blog some much needed attention and I've also been able to get almost caught up on the backlog of blogs that I follow. In my reading, I have come across a number of gems of wisdom that I think are well worth sharing:

James Bach in Why Scripted Testing is Not for Novices
  • [A] scripted tester, to do well, must apprehend the intent of the one who wrote the script. Moreover, the scripted tester must go beyond the stated intent and honor the tacit intent, as well– otherwise it’s just shallow, bad testing. - TW: This problem is a direct result of divorcing test design and execution. And for a novice tester, they simply don't have the skills yet to "read between the lines" of the script to see the intent.

Michael Bolton in Why Checking Is Not Enough
  • But even when we’re working on the best imaginable teams in the best-managed projects, as soon as we begin to test test, we begin immediately to discover things that no one—neither testers, designers, programmers, nor product owner—had anticipated or considered before testing revealed them.
  • It’s important not to confuse checks with oracles. An oracle is a principle or mechanism by which we recognize a problem. A check is a mechanism, an observation linked to a decision rule.
  • Testing is not governed by rules; it is governed by heuristics that, to be applied appropriately, require sapient awareness and judgement.
  • A passing check doesn’t tell us that the product is acceptable. At best, a check that doesn’t pass suggests that there is a problem in the product that might make it unacceptable.
  • Yet not even testing is about telling people that the product is acceptable. - TW: I've been trying to promote this concept for at least a year in my own evolutionary understanding of my craft. You can expect my own blogging on this topic soon.
  • Testing is about investigating the product to reveal knowledge that informs the acceptability decision.

Michael Bolton in What Exploratory Testing Is Not (Part 3):  Tool-Free Testing
  • People often make a distinction between “automated” and “exploratory” testing. - TW: This is the first sentance and BAM! did it cause a paradigm shift for me!
  • That traditional view of test automation focuses on performing checks, but that’s not the only way in which automation can help testing. In the Rapid Software Testing class, James Bach and I suggest a more expansive view of test automation: any use of tools to support testing.

Anne-Marie Charrett in Please don't hire me
  • If you want me to break your code - TW: This set my brain going for at least two hours thinking about the implications of this. It's a great point though, testers don't break code. Look forward to more on this in the future.

I hope you find some wisdom in this too.

Thursday, March 15, 2012

Counting My M&M's

Like millions of other Americans, I keep a stash of munchies in my desk drawer at work. I find that a little treat in the afternoon is a highly effective way to keep me focused on my work. One of my snacks, interestingly (or oddly), has evolved into a bit of a ritual.

It all started back in 2010. I was at my local Dominick's before work picking up a donut, something for lunch, and stock for the stash. I happened down the candy aisle and saw that they had the jumbo bags of M&M's on sale. I'm always a sucker for the lowest price per unit so I couldn't resist. Fast forward to the afternoon-snack time-and a funny little thought popped into my head: "Are there the same number of each color of M&M's in the package?" I decided to find out, just for the heck of it.


The jumbo sack of M&M's is 42 ounces so there are two things to keep in mind. 1. I do not eat the entire thing in one helping. 2. I was not about to dump out the whole sack and count them right then and there. Instead, I started a spreadsheet. Whenever I decided to have a handful of M&M's, I would first sort them by color, count them, and then record the stats in my spreadsheet. It didn't take too long for multiple passersby to notice and remark upon my method for eating M&M's. Suddenly I had a reputation that needed to be maintained! Never again could I reach into a sack of M&M's and NOT count each color.

Two years later, I'm now on my fourth sack of M&M's. I don't eat them every day and I don't always have them in my stash. But when I do, I keep statistics. Today, I am pleased to announce the public sharing of this information on my M&M Counter page!

The M&M Counter page has several fun features:
  • The graph at the top shows the combined stats for all of the M&M's that I have consumed over the years.
  • Then, I provide a graph and chart that are updated in real time that show the stats for the sack that I'm currently in the process of devouring.
  • Finally, I have provided a form, for what I think is the most exciting feature of all, to allow YOU to join in the fun. You are welcomed and encouraged to contribute your own counts. Currently, the form only supports the regularly colored candies. Pick the closest option when selecting the size of the package. Soon, I will include a graph or two to display the user submitted data.
So yeah, it's a little weird. There's nothing scientific about this. There's no ploy to identify certain colors as subject of discrimination. It's just for fun. Enjoy!

Paper Airplane Science Experiment

When I was in elementary school, we would have a science fair every other year and all of the students would do some sort of science project. In fifth grade I simulated acid rain and in seventh grade I made recycled paper. I didn't find the acid rain experiment to be fun at all and it had been the only thing I could think of. The paper experiment was more fun because I got to make a big mess but it still didn't engage me, even though it was something I really wanted to do. So for  you parents out there trying to help your kid find something different to do for a science experiment, here's an idea: PAPER AIRPLANES.


Lots of little kids like making paper airplanes and if you think about it, it's super-simple to turn it into a science experiment and there's a a number of different approaches that you can take. The idea when doing different experiments, is that you want to identify all of the different variables and then just change ONE. In any approach, you'll form hypotheses around the same questions:
  1. Which airplane flies the farthest?
  2. Which airplane flies the straightest?
Experiment Method 1: Airplane design
Go online (or to the library) and find instructions on how to create several different designs of paper airplanes. Then construct them using the SAME size and type of paper. If you want, you could measure the wing dimensions and area and use those numbers to form your hypotheses.

Experiment Method 2: Airplane material
Pick a single airplane design and change up the type of paper used. Make sure the size of the paper doesn't change though. You could use construction paper, aluminum foil, printer paper, wrapping papper, cardstock, or whatever else you can think of. Here you'll probably want to weigh each airplane and use that for forming hypotheses.

Experiment Method 3: Airplane size
Again, pick a single airplane design but this time change up the size of the paper but use same type of paper. You may need to cut down large pieces of paper to make smaller planes. I say, find the biggest cut of paper you can find. Most schools have large rolls of paper for making big posters or bulletin boards. For each variation, make sure that the length to width proportion of the paper remains constant.

Experiment Method 4: Airplane proportions
Pick a single airplane design and type of paper. This time, vary the dimensions of the paper, while maintaining the same number of square inches. For example: (12x10) and (15x8) both have 120 square inches of area. You could also do (12x10) and (10x12) - rotating the axis of the plane. In doing this type of experiment, you should take lots of measurements in forming your hypotheses: wing area, plane length, wing width, plane height.

Conducting the experiment
Reduce the potential for errors:
  • I would make three copies of each plane to try to account for any variations there might be in the construction. Also, practice making the plane first and then make new ones for the experiment.
  • Throw and measure each plane at least five times. The more times you throw it, the more accurate your data will be, unless, of course, the plane gets really beat up from doing a nosedive into the floor. You can always disregard measurements (so you take 10 but only use the first 5 because you see that after that the data started to skew from bent noses).
Location selection:
  • You should try to find a wide open place to throw the airplanes. The school gymnasium would be a great place because it's wide open and there won't be any wind.
Location preparation:
  • Place a mark on the floor from where you will launch the planes each time (Use gaffers tape in the gymnasium so you don't gunk up the floors!). Mark out a straight line from that point. You might want to put a target on the wall or something that is in line with the starting point and straight line. When you throw the planes, aim for the target and that will help ensure that you throw consistently.
Throwing:
  • Again, aim for the target and make sure that your throwing arm is lined up with your target.
Measuring:
  • Measure the distance from the throwing point to where the plane LANDED. Have someone there to help watch in case the planes want to slide on the floor.
  • Measure the angle between the center line and where the plane lands.
One Last Idea:
You could also experiment with airplane surface friction. I don't know how you would MEASURE friction though so I'm just floating this out there for you. Using glossy inkjet photo paper, the same size paper, dimensions, and airplane design, make one plane with the glossy side out and one plane with the back side out.

Share Your Results
If you decide to try this experiment in one form or another, please share your results. I would love to hear what you discover!

Wednesday, March 14, 2012

Editior Fail at Yahoo! News

While browsing the news at Yahoo! over my lunch break on my way to read Dear Abby, I noticed this rather prominent error. Don't rely on spell checker!

Tuesday, March 13, 2012

Predator II: Just Die Already!

What do they do in in Hollywood if a movie does well at the box office? Make a sequel and use the success of the first movie to milk consumers for more money. Predator did well, earning almost $100M so naturally, Predator II came along three years later. Sequels usually have a common relationship with the original. In the first movie, the hero, after great struggle, finally kills the villain and then the sequel comes along and somehow the villain is back to life causing even more havoc. I see that and get to thinking, "Gosh darn! Why won't that thing JUST DIE ALREADY!?" I ask that question about software defects often because often times, defects have sequels too (and so should blogs)!

Despite my best efforts - thorough coverage, testing every test case I can think of, making sure everything WORKS - out of nowhere pops up some bug that I thought was squashed weeks ago! Sometimes it doesn't matter how big your muscles are, how many bullets you have in your gun, or how many other people have their guns pointed at the same monster, they still come back to life.

This can be caused by any number of things. It could be laziness on the part of the tester (or the developer) but I don't think that's usually the case. Here are some other causes:
  1. Unclear requirements
  2. Inexperience
  3. Lack of time
  4. Introduction of new/altered code
  5. Using [testing] the software in a way that it wasn't previously used
That last one is a big ball of mud - "WHY DIDN'T YOU TEST IT THAT WAY BEFORE???" See causes 1-4. The truth is, software is extremely complex and it's impossible to account for every scenario. As a tester, you must know how to prioritize and how to look for the scenarios that are most likely to occur and those which have the gravest consequences because there just isn't time/budget/people-power to do it all.

When defects do reoccur, use it as a learning catalyst. Was there an obvious breakdown in the development or testing methodology? Is this a "new" method of execution that should be noted for the future and with application other scenarios? Is there a different testing technique or tool that might have been able to expose that the defect was not fully resolved earlier?

Old defects will continue to pop up. Don't be discouraged but remain vigilant. Keep sharpening your skills and be ready for the enemy to return, because he always does, sometimes with Aliens.

Please study for my interview

I recently volunteered myself into the position of reviewing resumes, identifying candidates, and executing first round interviews for a QA position at my company. This has been a real learning experience for me as I've garnered a better understanding of the hiring process; but more so, it has been an eye opening experience. The great majority of applicants in the field are ROBOTS, figuratively speaking. Requirements get turned into scripts and that's how you test. As long as you have the right process, the right charts, the right formula, that's all you need.

I disagree. Don't get me wrong, I want someone that can transform requirements into test scripts but I what I really want is someone that can THINK. Someone that can test what's not in the requirements document. To quote Anne-Marie Charrett, I want to hire someone that says, "Don't hire me if you want perfect software. Don't hire me if you're looking for a tester to only "check" if things look ok."

For my interviews, I developed a standard list of questions to ask. Each question was carefully thought out and has a specific purpose for being asked. Here's my list:
  1. How did you get into software testing?
  2. What do you like about testing?
  3. What are your frustrations with testing and how do you deal with them?
    1. For example: How do you deal with being the resident naysayer?
    2. For example: How do you deal with defects that just never seem to get fixed?
  4. What comes to mind when you hear the term ‘Quality Assurance’?
  5. Compare and contrast automated and manual testing.
  6. Compare and contrast scripted and exploratory testing.
  7. How confident are you in your ability to deliver defect free software?
  8. What essential information should be included in defect report?
  9. How do you determine if something is working correctly when you have no documentation?
  10. What’s your experience with Agile?
  11. How do you sharpen your testing skills?
So there you go. If you're ever on the other side of the table being interviewed by me, nothing I ask should catch you by surprise. In fact, I encourage you to study for my interview. However, for now, I'm not going to explain any of my rationale; you'll have to come back for that later. For those of you that conduct interviews yourselves, is there anything you think I should add? Please share in the comments.

Monday, March 12, 2012

Using XQuery in MS SQL for Novices Part 2

How to use the value() function

Just the other day I started the conversation about how to use XQuery functions in SQL to pull specific XML data out of a table. It's time now for Part 2.

In the first discussion, I explained how to use the query() function. It's a very nice function because it returns both the XML nodes and the data within them. However, if all you want is the specific data in the node, having the nodes display in each result can make it more difficult to read the results. For this purpose we can use the value() function.

The value() function is ever-eager to throw the error "'value()' requires a singleton (or empty sequence)". It's also eager to throw the error "The value function requires 2 argument(s)." Obviously, these errors occur when we don't provide all of the necessary information.

The two arguments required by the values() function are:
  1. The reference to the node
  2. A data type specification in which to host the returned information
The requirement of a singleton is admittedly, not something I fully understand. It is solved, however, by appending a number one in brackets - [1] - to the end of the first argument. Just put everything inside of the single quotes and the argument itself inside of parentheses.

This is how it looks:
SELECT XMLColumn.value('(//XML-Node-Name)[1]', 'DataType(#)') FROM Table
Don't forget to add a comma between the arguments!
 
We can further tidy up the results by aliasing the column (assigning it a custom name of our choice) and using the exists() function.
SELECT XMLColumn.value('(//XML-Node-Name)[1]', 'DataType(#)') 'Alias Column Name' FROM Table WHERE XMLColumn.exists('//XML-Node-Name') = 1

Sunday, March 11, 2012

What should be the easiest archaeological dig in the world

When I entered the field of software testing, the last last thing on my mind was archaeology. Software testing is about the future whereas archaeology is about the past. Technology is clean and non-physical but archaeology is dirty and labor-intensive. However, the two fields aren't all that different. A good software tester is going to thrive on artifacts, but not the kind buried in the ruins of ancient civilizations.

In software projects, an artifact is any piece of documentation that relates to the project:

  • RFP
  • RFP Response
  • SOW
  • Project Plan
  • Requirements
  • Design comps
  • Story boards
  • User personas
  • Test scripts
  • Defect reports
  • Meeting summaries
  • etc.
The artifacts mentioned above help software testers the same way bones help paleontologists. Both are vital in the acquisition of knowledge. Testers need to have a thirst for project knowledge. How can one assert if the product works as intended without having an authoritative source? Regardless of approach, the more the tester knows about how the software is supposed to work, the more thoroughly they can test through broader coverage and more intricate scenarios.

When projects don't have a decent amount of documentation, you're asking for scope creep and unsatisfied client expectations. Testers, get dirty and dig into the documentation. Insist on having access to it and demand it early. Study it thoroughly. Use it to help design your tests. If the documentation doesn't exist, consult the project experts (well, consult them anyway) and then write it down. Once it's written down, it can't be disputed - it might be changed later but that can happen to any document. Moral of the story: use everything at your disposal to learn about the project.

Friday, March 9, 2012

Using XQuery in MS SQL for Novices Part 1

A recent project at work presented me with a new challenge. Generally in a database, at least the ones that I've  had to work with, each different type of data is stored in its own column. Well, the project currently under test downloads information from a third party system in the form of an XML file. Even though we don't use every bit of data in provided by the third party, we still want to preserve it in its original format. Therefore we store the entire XML string in the database.

When XML data is stored in a database, there are at least a couple different data types that can be used.
  1. It could be stored as just regular old text using the varchar data type. In that case whatever program is using the data has to convert it back into XML in order to use it. The Umbraco content management system likes to do it this way.
  2. On the other hand, it could be stored natively using the XML data type, which is what our system does. Storing the data AS XML presents some interesting challenges as well as many opportunities when it comes to digging for information within the XML string itself -- most of which I'm still figuring out. For today, I'd like to start with just the basics.
Doing It Old School
If all you're trying to do is find the rows where a specific series of characters occurs, you can search just like you always do... almost. 
SELECT * FROM Table WHERE XMLColumn LIKE '%key-text%'
This traditional query will throw an error faster than a lazy developer's code. Instead, you need to change data types on the fly:
SELECT * FROM Table
WHERE CAST(XMLColumn AS varchar(max)) LIKE '%key-text%'
So to reiterate, this query uses the CAST command to convert the XML column into a text data type.

Being All Fancy About It
Like I said, the old school works fine if you're just trying to identify entire records in the table that match your criteria. If you're just looking for specific nodes in the XML data, the approach above is NOT very efficient. You can harness the power of the XML data type to do things much more quickly! Since v.2005, MS SQL Server has supported XQuery. I'm not a programmer so I don't yet understand the full power that this yields. I've found, however, that the existing help on the internet was not written for people like me so here's what I've learned so far:

STEP 1: Using query()
Assuming that we just want to find the data stored in a specific XML node, we can use the Query() function.
SELECT XMLColumn.query('//XML-Node-Name') FROM Table
A couple of notes about what's going on there:
  1. Query() is a function. Inside of the function is one ore more arguments (RAWR! J/K), which are written inside of the parentheses. Each argument must be enclosed in single quotes and multiple arguments are comma separated. The query() function will accept accept ONE argument.
  2. The double slashes // at the start of the argument tell the system that you're looking for a node and for our purposes, it doesn't matter whether it has child or parent nodes.
  3. You need to put the goods of the function inside of the single quotes.
  4. The node name is CASE SENSITIVE
  5. Don't capitalize the the function: e.g. type "query" not "Query"
When this query runs, unless you add a WHERE clause, it's going return a result for every single row in the table, including the rows where the specified node does not exist. If the node does not exist for that row, there will be an empty cell in the results table. If the node does exist, the data returned will look like this:
<xml-node-name>XML data stored in node</xml-node-name>
STEP 2: Using exists()
Because using query() alone can be a little messy returning empty rows, we can use another function that checks YES or NO does something exist in the XML data.
SELECT XMLColumn.query('//XML-Node-Name') FROM Table WHERE XMLColumn.exists('//XML-Node-Name') = 1
 This query will only return the rows where the specified node exists without any empty rows. A couple of notes about what's going on here:

  1. I used the same argument for both functions because if the node doesn't exist that I'm looking for, that row doesn't need to be returned.
  2. The = 1 part is telling it to evaluate to TRUE (e.g. Yes, it exists) whereas, if I set it to = 0 it would be the opposite (e.g. No, it doesn't exist). Setting it to 0 would only return the blank rows in this example.
Please let me know in the comments if you've found this useful. Look for more posts to come as I learn to harness more power of the XQuery!

Helpful but technical links (also probably the first ones you came across when googling "XQuery SQL Server":

Friday, November 18, 2011

Collaborative Cursing SQL Style

Earlier this week at work, I had some discretionary time. I'm not quite sure what inspired me but I decided I wanted to brush up on my SQL scripting skills.  I'm not by any means a SQL scripting pro but I know how to find the data that I'm looking for. In my line of work, I'm generally just looking to verify that the data being written to the database is correct. Generally a simple query will do the trick but occasionally more complex scripts, like a cursor or a loop, make it easier. Unfortunately, I couldn't remember how to write a cursor. Oops. In fact, I couldn't even remember what they were called. Oops again. But that's why I wanted to practice so that when I actually need to write one, it'll be easy. I finally figured it out with the help of Google but I still ran into a couple of bumps in the road. The end result does work but I welcome tips for improvement.

Here's my cursor:

DECLARE @total int,
  @city varchar(64),
  @state varchar(16),
  @table char(64)

DECLARE city_cursor CURSOR FOR
 SELECT DISTINCT City, State FROM MyAddressTable
 ORDER BY City

SET NOCOUNT ON

CREATE TABLE #City_Count_Temp
 (
 City VARCHAR(64),
 State VARCHAR(16),
 Total INT
 )

OPEN city_cursor
FETCH NEXT FROM city_cursor INTO @city, @state

WHILE @@FETCH_STATUS = 0
BEGIN
 SELECT @total = (SELECT COUNT(City) FROM MyAddressTable WHERE City = @city and State = @state)
 
 --SELECT @city AS City, @state AS State, @Total AS Total
INSERT INTO #City_Count_Temp VALUES (@city, @state, @total)
 
 FETCH NEXT FROM city_cursor INTO @city, @state
 
END
CLOSE city_cursor
DEALLOCATE city_cursor

SET NOCOUNT OFF

SELECT * FROM #City_Count_Temp

DROP TABLE #City_Count_Temp
It's actually a pretty simple script. The purpose of the script is to count the occurrences of each city in the table and then output it into a nice pretty list. It accomplishes this by first querying the table for the unique list of City/State combinations. Then using this list it again curses through the table counts the number of occurrences of each and dumps the information to a temporary table. Finally, there's  a simple query of the temporary table that produces the final list.

So the bumps in the road that I couldn't quite figure out... First, the only way I could get the script to make a pretty list was write the data to a temporary table. You might have noticed a commented out line in the middle. Originally, this was how the script provided the output without writing to the temp table. The problem was that SQL Management Studio displayed a separate result for each curse of the script. If there's another way to do this, I'd love to know!

Also, I tried to set the table name (MyAddressTable) as a variable but for some reason, it would error every time saying that I needed to declare the variable (even though I had declared the variable).

So that's my little cursor. I'm happy to answer any questions about it. I'm also happy to receive any suggestions about how to improve it

Saturday, May 7, 2011

Rules for Driving in Chicago

  1. Watch out for the taxis - they are the absolute worst drivers there are
  2. Watch out for the out-of-towners - possibly even worse than the taxi drivers, you know the taxi is going to cut you off but out-of-towners are just plain unpredictable
  3. Watch out for the buses - they'll cut you off too so just stay out of the buss lane
  4. Watch out for the bikers - they're incompetent when it comes to obeying the rules of the road
  5. Know where you're going and how to get there
  6. NO LOLLY-GAGING! Keep up with the traffic in front of you, if you're going to make a turn then TURN. To sum it up in one word: Commit
  7. If you're not in the correct lane to make your turn, don't stop at the intersection and expect someone in the turn lane to let you in while you hold up everyone behind you - go around the block
  8. Watch out for pedestrians
  9. Watch out for bikers II - there are a lot of them, often they have their own lane so give them their space (don't cut them off when making a turn and look before you open your door when parking on the street)
  10. Watch out for potholes - they're deep, jagged, and everywhere
  11. Watch out for people double parked
  12. When turning, get all the way over in the turn lane or to the edge of the street
What have I missed? Feel free to add more rules in the comments.

Monday, April 4, 2011

Concerned About API Healthcare's Acquisition? What You Can Do

I know I'm not the only one that hopes Kronos' acquisition of API Healthcare falls through. I also know that most people don't feel comfortable talking about it for fear of their jobs. THERE IS SOMETHING YOU CAN DO. Contact the Federal Trade Commission.

The FTC, in conjunction with the Department of Justice, is the government agency that approves mergers and acquisitions and makes sure that antitrust laws aren't broken. If you think this is a bad idea, contact the FTC.

Here are your options:
By email: antitrust@ftc.gov
This method isn't considered confidential, so if that's a concern...

By mail:
Federal trade Commission
Bureau of Competition-H374,
Washington, D.C. 20580
If you mark the mail "Confidential" it will be treated as such.

By phone:
1–877–382–4357

As I understand it, the FTC has issued a second request for information. They don't always do this so hopefully it means they see a potential problem. It also means time is fleeting so ACT NOW.

For more information, visit ftc.gov or view this PDF from their website that gives a nice overview.

Sunday, April 3, 2011

API Heathcare's Acquisition by Kronos Remains Unpopular

My feelings about the pending sale of API Healthcare to Kronos is no secret. I think this is a horrible idea. As it turns out, I'm not the only one that thinks this. I have it on good authority that in addition to me, but the API employees AND customers are not in favor either!

Two and a half years ago when Francisco Partners bought API, there was a lot of uncertainty. The employees knew things were going to get shaken up. There was a shake up and really, I would say that the operation of the entire company  changed. The balance between making money, providing a quality product, and treating employees fairly shifted dramatically. I hate to say it but employees were on the losing end of that switch. Nonetheless, the core focus of the company remained steadfast and probably even got more precise. Because of that focus, the vast majority of employees remained loyal to the company. There were only a handful of employees that left or were let go.

Fast forward to 2011. Employee retention has become a big problem. I don't have exact number of departures but I'll let you draw your own conclusions but it's pretty obvious that there's a problem when the company has to resort to bribery. If you were a customer right now, how would you feel knowing employees are jumping ship?

Rumor has it that the clients aren't any more excited about this either. Why would they be? There are two major competitors in the market. They chose API over Kronos for a reason and now they're potentially being forced into using a product they don't want or with a company they don't want to work with.

If ever there was a time for the regulators to step in and say, "NO!!!" this is it. Competition is good for the market and for consumers. There is nothing good that could come of this acquisition. All Kronos wants is to eliminate their biggest competitor because that will translate to more money for them AND they won't have to work as hard to try to maintain some sort of edge in the market.

Monday, March 7, 2011

Shrinking Screens

About four months ago, I started thinking seriously about upgrading my laptop. Basically, all I use it for is surfing the internet and email but even that seems to take longer and longer than it should. For a while I contemplated going the table route but I really want a physical keyboard and I find the laptop configuration is easier to use when laying on the couch or in bed.

I won't indulge you with my list of "must haves" just yet but one thing I want is a high resolution screen. As I was looking around, I discovered two interesting trends. Most laptops now have a 16:9 aspect ratio. This makes sense since TV's are all 16:9 now however, it seems that the common aspect recently was 8:5. Personally, I like the 8:5 ratio.

The second observation I had is that screen resolution leaves much to be desired. Just about every model from every manufacturer I looked at only had displays at 1366x768 for sizes up to 15". That's not good enough for me. The manufactures like to "fancy it up" by calling it "720 HD" which is true but clearly a marketing ploy. I realize that full HD (1980x1080) will come at a premium and only be available on a small range of models. However, to not even be able to upgrade to something somewhere in between (around 1600x900) while not breaking the bank is disappointing. Even if I wanted a behemoth 17" laptop, the standard res is 1600x900 and it's next to impossible to find an upgrade. Is this just not important to enough people to warrant offering more upgrade options?

What I find particularly odd about this is that there is more and more buzz about the resolution of smart phones and tablets. My Evo is 800x480 for crying out loud and it's only 4.3"! Meanwhile complaints abound that the iPad 2 is still at 1024x768.

Are my expectations just too high? Should I just become a mac instead?

Saturday, February 26, 2011

API Healthcare Looks to the Future with Synergy

Yesterday I wondered aloud about API Healthcare's vision for the future and whether they even have one. I'm happy to learn that they do. Historically, HIMSS has been API's marketing focus for the ear. As such, they usually have some big announcement for the convention to stir up some buzz for the company. From what I've heard, they didn't have any new announcements but they did focus on their new platform, Synergy.

API made it's official announcement about Synergy on February 1 so they let the cat out of the bag before the convention. But I'd concede that the announcement was recent enough for it to be still fresh and largely unknown at HIMSS. Synergy is a big deal though and it's an exciting advancement for the company because it takes their vast array of products and unifies them on a single platform. This project has been in the works for years and it lays the foundation for the future but I don't know how it fits in with Kronos.

Previously, all of API's products were independently developed and engineered using a variety of technologies. The single platform brings them together in one seamless integration. It makes the whole system more efficient, easier to troubleshoot, and easier to expand. Think of it this way, if you put a slice of lassagna, a scoop of German potato salad, and some pickled herring on a plate, you'd have a well rounded meal. They might even all be things that you like but they don't really go together even though they get the job done. On the other hand if you put a cheeseburger, fries, and fresh corn on the cob all on the same plate, you have a meal where each component enhances the others. The flavors don't compete with each other. It's a weak analogy but I think you get the picture.

So, API has finally perfected their menu (hopefully just as Ryan Braun's Graffito). They are definitely ready to charge ahead. But then there's this acquisition business. It sounds to me like all this work is not going to reap the rewards that it could or should because obviously Kronos' software doesn't run on API's platform.

I really hope API gets to continue to operate largely independent of Kronos. This company has been working so hard and they have real vision for the future. And since I say that, I need to give credit where credit is due and that's with the CEO, J.P. Fingado. It would be a real shame otherwise.

P.S. I just had this unrelated thought: I wonder if Luis would have bought the company back rather than let it go to the enemy if he had had the chance?

Friday, February 25, 2011

Good News Remains Elusive for API Healthcare

Kronos detailed some more of its plans regarding its acquisition of API Healthcare at the 2011 HIMSS conference. For those of you that don't know, HIMSS is probably the largest healthcare information technology organizations in the world. They have a conference each February and it is enormous. In fact, only a handful of cities can host it because it's so big.

If there's any good news, it's that API's current solutions will continue to be supported. Of course, there's no word about continuing to develop them or actively market them to new customers.

They're pretty clear that they plan to combine the best from each product line. To me this sounds like ransack and pillage.

I think what is most telling though is their overt excitement about obtaining the patient classification system (PCS). What that system does is it calculates staffing levels based on patient needs. So if you have a lot of critically sick patients, it will show you that you need more staff to come in and which staff members will best fill the need, and how you can do it for the lowest cost. This, too, is an area that is being increasingly regulated. To my knowledge, API's PCS is a revolutionary technology in the industry and Kronos had nothing to match it. Because of the regulation in states like California, Kronos couldn't put up much competition.

Since jobs are a hot topic, let's talk about that. Sales and training staff are no longer needed. Engineering staff can be cut down to a skeleton crew for support issues. Configuration analysts can be reduced soon since there won't be new implementations. Tech writers are no longer needed. HR? Goodbye. Management? Goodbye. About the only group things look okay for are the support personnel.

Again, I hope to be proven wrong. PLEASE, prove me wrong! But what good comes from eliminating the biggest competitor in the market with an exclusive cutting edge technology?

P.S. Historically, API has always had some big announcement to make at HIMSS. I haven't been able to find anything about one this year. This is yet another sign of what's to come. No news is bad news because it says that the company is does not have anything exciting to announce about its future.

Thursday, February 24, 2011

Ode to Software Testing

I also blog occasionally on my company blog. I wrote a song about software testing last week. You can check it out here and search for past articles I've posted there.

P.S. My company is hiring - click here to see the latest.

Kronos' Acquisition of API Healthcare Is Only Good for Kronos

It was announced on February 7 that Kronos would acquire API Healthcare. This is not good news for anyone but Kronos. It is not good for API employees. It is not good for API customers. I suppose it may be good for Kronos customers in the short term but that remains to be seen.

Who Am I
Who am I to talk you ask? A former API Healthcare employee. I worked there for three years-two years under the original ownership and one year under Francisco Parterns' ownership. I liked working there. I had great coworkers. The management was professional. The company had drive. It was a trifecta for happy employees. The only reason I left was because after meeting my life partner, we decided to start a new life together in Chicago. Unfortunately, Francisco Partners has sold everyone out, in my opinion.

Why This Is Bad
So what's so bad about this? API Healthcare has had a laser focus on the healthcare industry. Everything they make is custom engineered for medical professionals. This means there are no half-ass solutions that try to maximize profits by stretching a single product across multiple industries. Don't get me wrong, the proverbial death of two birds with one stone is a good thing. Healthcare is such a unique industry though. The pay rules for nurses and other support staff  can be so convoluted. Government regulation is extensive and it varies wildly from state to state. This is a 24/7/365. To be a leader in this field, you need a laser focus.

Kronos has been trying to acquire API for as long as I know and certainly longer. API has been Kronos' biggest competitor. Kronos has solutions for a multitude of industries. And of course, their healthcare division simply doesn't have the precision of API. Because of Kronos' size though, they have a respectable market share despite their inferior product.

I would bet money that API employees are going to lose their jobs. Once Kronos gets their hands on the software, they're going to rip it apart, reverse engineer it, and shove it into their own product. They'll only keep API employees around to execute the carnage.

I would also bet money that API customers aren't going to be happy with the results. Kronos still will not have the laser focus. The product is going to get dumbed down and exploited and it's not going to work as well or have the same drive for improvement. Additionally, nothing good ever comes when competition goes away. Sure, there are a handful of other companies in the market but they're peons compared to what's to come. But it's not like Kronos is adding new solution to their portfolio, they're just eliminating the chief competition. Competition has forced both API and Kronos to keep raising the bar. There's no need to do that anymore. Hospitals will be backed into a corner and forced into using a shoddy product because there will be no other choices.

Please Prove Me Wrong
I hope to be proven wrong but I just don't see any silver lining to this. There's one last thought that I want to express. When Francisco Partners bought API from Luis Garcia, they were quite vocal about how they bought companies as long-term investments. They've only had API for two years, which is not very long. I wonder how long Kronos and Francisco have been in negotiations...