Thursday, February 16, 2012

Ready, Aim, Deep Breath, FIRE!!!

I've been on pins and needles the past couple of days.

As I said in my last post, I've been given the opportunity to write a book on a topic that is near and dear to me (yeah, I'm still being a little cagey because it's not a done deal, but it's looking very likely at this point).  What helped me talk myself off the edge? Actually, I didn't, a friend and compatriot did.

To give just a little more back story, I was sent a proposal for a book that ranges in scope from complete beginners to domain experts and everything in between. It's a title about a technology that I have used in the past, but I felt less than expert at it (and in many ways, less than expert is putting it kindly). However, I was also reminded that I had vivid memories of the frustrations that other people feel when they try to learn something new.

Often we start with trivial projects that we skim through because we feel way too silly actually doing them. They're so obvious after all. The problem often makes itself manifest after that gentle introduction. Now we're expected to have fairly deep domain knowledge and a more than passing understanding of what we are working with. It's like we were introduced gently and with great care to A, B and C... and then we pick back up again with K, O, Q and S. What happened with everything in between?!

The challenge is that we have a lack of context in general and a lack of personal context in particular. Some books get this balance right, while others miss it entirely. Having gone through the process of "Learn Ruby the Hard Way", I feel like I have had a really good model on how to do it where a natural progression can be shown and developed that is direct and terse where necessary, and also verbose and focused where also necessary. It also makes the point that to get it, you have to do it, and do it often, and do it in different contexts.

Still, I had that nagging feeling... what if I can't answer the tougher questions. What if I am limited my my own Peter Principle? How can I overcome that? The answer came as an email from a friend and collaborator. He excitedly emailed me and said "Hey, I know this is out of the blue, but how would you like to write a book?!" In his forward was the exact same proposal that I had received. I already know that the level of domain knowledge in this case for my friend is very high,and with that, my prayers were answered. Between us, we think we can do this justice.

And that's exactly what we proposed, that the two of us work on it together... and the reply back so far is a "yes". Note, this is very early in the process, and it's possible that any number of things could prevent this from happening, but I'm choosing not to dwell on that. Instead, I'm going to roll up my sleeves, work with my collaborator, and see if we can hit this one out of the park. Anyway, I can't wait to tell you what we have up our sleeves, but until we have something  notated and signed, y'all are just going to have to wait :).

Tuesday, February 14, 2012

Pulling the Trigger

One of the most terrifying things to do is to stare down a project or an idea that seems exciting, has a great potential, and the chance to grow and develop because of it is interesting and could really be a great growth opportunity. Yet we also often see these chances as dangerous and reckless. Are we up to it? Do we know enough to really do the topic justice? If we do, how do we know? If we don't, how do we know we are in over our head?

The reason I am asking these questions is that I have an intriguing offer. It is the possibility of writing a book for a publisher that I've done reviews for, and it covers a topic that I have some experience with, but don't consider myself an expert on the topic by any stretch. I could make many excuses as to why I could disqualify myself from doing the project... and yet, there's a part of me, that wannabe bold intrepid explorer, that has seen so many times that topics are only as mystical and mystifying as we make them out to be. Additionally, many topics are only as mystifying as the previous generation of authors that have written about them.

You will notice that I am being deliberately vague about this... that's because I don't believe in talking out of turn about things that may or may not come to pass. There's the "bold boast", and then there's shooting one's mouth off and making a fool out of one's self. Yet I've stepped back and looked back at my Book Club reviews for "How We Test Software at Microsoft", "How to Reduce the Cost of Software Testing" and the experiences of my Practicum posts for "Selenium 1.0" and "Learn Ruby the Hard Way". I've realized that I've learned way more about structuring these projects than I ever thought I could. Additionally, I've learned way more about the respective products and concepts than I ever thought I could, both the ways that things work as well as the irritating issues when things don't work as well as they should.

So this brings me to a fundamental question... does one wait until they are expertly knowledgeable about a topic before they plunge into writing about a specific topic, especially if it has to do with a particular product line or approach? Does the process of dissecting the topic at hand and digging into it to write about it in "layman's terms" make the difference between the casual practitioner and the expert?

I don't have the answer to these questions just yet, and truthfully, it's up to the publisher to decide if they feel I'm the dude to do this, or if I'm one of a number of contributors... or if they feel I'm worth working with at all for this. At the end of the day, all I can be do is be honest and show both my experience and my ignorance. I may not be an expert on the topic in question, but I know enough to know what frustrates people, and maybe, just maybe, that might be the most valuable thing that I can offer to see it through, because I truly would love to see a book on this particular topic be available... and really, that's all you are going to get out of me about it :).

I'll just have to see if, after an honest and truthful assessment of what I can really do, if they will be willing to entrust such a project to me. If they are, then, well, I guess I'll have to see if I'm man enough to pull the trigger at that point :).

Monday, February 13, 2012

Book Review: The Linux Command Line

What if you had a book that took you from the very beginning of the Linux command line options, and it took you through progressively interesting and relevant topics so that you really could develop a mastery of the shell? Oh, and what if it were written in a fun style that was less wonkish and easier to embrace and follow along with? Less tech, mode dude. William E. Shotts, Jr.'s “The Linux Command Line” manages to do that.


Let’s face it, learning the entirely of the Linux command line can take years. It’s unlikely most will walk through the book page by page and work through each example, but with this book, it feel like you could do exactly that and not get bored.


The first part of the book walks the user through the many commands that are relevant to all systems and all shells; the navigation options through directories, showing files, getting your head around terminals, finding and opening files, moving files and directories around, links (both literal and symbolic), learning about commands and how to learn more about them. All of this, as well as redirection, using pipelines, creating filters, expansions, and so on. A wonderful metaphor and explanation made in this section is that Windows is like a GameBoy, and Linux is like the world’s biggest Erector Set. While Windows is nice and shiny and makes for pretty applications, it’s difficult (relatively speaking) to roll your own applications without a fair bit of knowledge and packaged tools. Linux, on the other hand, right off the bat gives you all the tools you need to build just about anything in just about any conceivable way you might want to build it. 


Part 2 covers configuration of the shell and the environment variables that it keeps track of. Shell variables like DISPLAY, EDITOR, LANG, PS1, TERM and many others are explained and we get to see how simple shell scripts are implemented allow us to access and modify these values. We also get introduced to a variety of test editors, but with an emphasis on vi (and a mellow focus at that). The section is rounded out by learning how to modify the command prompt that we see and make it show us more details (directories, colors, etc.). 


Part 3 is a grab bag of all sorts of things that we often look at separately, but when taken together, make a lot of sense. We start with package management and making sure systems are up to date. Next we cover understanding file systems and the variety of commands that helps to mount disks, examine file systems, check and repair systems, get online and check the network for connectivity, copying files over a network and connecting via secure shell, performing archive and backup steps. The section end with a broad discussion on regular expressions, text formatting and processing and, finally, printing out files and compiling applications. 


Part 4 ties it all into the true big bad voodoo of the command line, the ability to write shell scripts. The section starts out with a fairly basic script formatting and then moves on to create a program that displays system information in HTML format. Along the way, we get to see how to use the shell and all of its properties and the huge toolkit of Linux commands to structure our work, and get an introduction to “top down design”. Subsequent chapters carry us through common development topics such as reading input from the command line, strings, numbers, variables and constants, and the variety of flow control ranging from simple branches to looping and case statements and arrays. The section ends with a grab bag of interesting topics including subshells, traps and error handling, asynchronous execution and named pipes.


Each section starts with the commands it will cover, walks through careful and thorough examples of each command, and then wraps with a simple explanation of the section covered, with sidebars aplenty. Seeing as this is a command line book, you bet that you are seeing a lot of the actual commands, and how they interact, how to apply permissions, manipulate text and manage processes. If you want practice with these things and not their graphical counterparts (and really, what “command line” book worth its salt wouldn’t make that its prime focus), well, you get your wish! 


Bottom Line: 


There are a lot of books that talk about the various Linux Shells, but you’d be hard pressed to find one that does so this entertainingly. Again, it’s the less tech (but not so much that the meat of the matter isn’t covered well) and more “dude” (but not to the point of being embarrassing or insulting) that makes this book a joy and a treasure. If you’re a novice Linux player, or just want to get beyond the pretty graphical wrapper of your MacBook, put this book at the top of your list.

Friday, February 10, 2012

The Watershed Moment

A couple of days ago, John Brownlee posted to the web site "Cult of Mac" what was an interesting picture. On the left, we see what cell phones looked like and were available prior to the development and the release of the iPhone. On the right, it shows what phones looked like after the iPhone was released.

Do you notice anything interesting? The first being that, in the first picture, there is a cacophony of different styles and formats for phones. Lots of different styles and features, many of which may be familiar to some and not so familiar to others. There is no question that many different varieties were to be seen and to be had. In the second picture, almost every phone looks as though it were styled and shaped like an iPhone.

What happened was that tech had a "watershed moment" with the release of the iPhone, and the rules of the game were changed. Yes, there were smart phones before, but no where near the sophistication of the iPhone at the time, and many other companies followed suit. The various Android phone manufacturers took many styling and design cues from the iPhone and made a system that was similar if not exactly the same. Even knock off phones not related to the iPhone or Android systems are following their design cues (I know, I have one).

In some ways, watershed moments are good, they show a definitive marker where things change, tastes align, and the world goes on a slightly different tangent than before. One needs just look at music to see similar examples through the years. Sinatra defined his era as clearly as Elvis defined his, The Beatles defined theirs and Led Zeppelin theirs. Add in Guns & Roses, Nirvana and later groups and you see what I mean. Oftentimes, those watershed moments obliterate all that has gone before... and frankly, that's a little bit sad.

As I've been thinking of testing these past couple of years, I've been able to look back and see some watershed moments as well. The ISO movement, and its brothers CMMI and Six Sigma. In the software world, the arrival of the record and playback tools, and perhaps today we could be seeing certification as a potential watershed moment in some places. My concern is not that these happen. If ideas are good and people embrace them, then there is nothing that's going to stop them and they will be adopted of their own accord. My fear is that much is being discarded that really shouldn't be. It's no secret that I consider the phrase "best practices" to be a terrible combination of words. I don't believe in them, but I do believe in various good practices that have their time and place. The danger with watershed moments is that they tend to sweep out many good practices because they no longer fit the fashionable "time and place" we are currently experiencing. 

In short, not everyone wants to move on from Elvis. Not everyone wants a big screen cell phone. And not everyone wants to have tools that make elaborate promises of "best practices" but don't really deliver. We want to be able to choose what works for us, whether they are fashionable or not.

Thursday, February 9, 2012

Book Review: The Secrets of Consulting


First, I'm doing this in reverse order. I actually read "More Secrets of Consulting" almost a year ago, and from that experience, I decided to read some more of Jerry Weinberg's books (Weinberg on Writing, Perfect Software, etc.). Thus it's a roundabout way that brings me to the original "The Secrets of Consulting".


This is a book that every tester is encouraged to read. If anyone asks other testers or programmers about which Weinberg books to read, invariably "TSOC" gets mentioned. So what do we get if we follow up and check out this now classic title (if we use automobile standards, anything over 25 years old is "classic").


First, this book is a fun read, and it's a quirky book full of American idioms that will really only make sense if you've grown up in the US or have family that has told stories of the US from the 40's on through the 80s (when this book was written). The anecdotes may feel odd to people who didn't grow up in the America of that time period, but for those of us who have, much of these details feel right and their amusement factor helps us remember the concepts.


Weinberg gives names to many of his principles that are whimsical, and that whimsical quality helps make them memorable. There are many folksy stories included, and if you have read any of Jerry's books, this is a hallmark of his writing. For some, it may be off putting. For me, I find it endearing. Having had correspondence and communication with Jerry over the years, you recognize his voice and his demeanor in the prose, and it makes the stories very authentic. As such, principles like the Law of Raspberry Jam, the Orange Juice Rule, Rudy's Law of Rutabaga, Marvin's Great Secrets, etc. become easily recognizable and easily remembered. By themselves, these names are meaningless, but it's the memorable stories that help them come to mind and make them ring true for me.


Don't let the folksy qualities of the book fool you, there is a lot of very practical advice in this book, and while the stories may make you smile, maybe even laugh, or possibly shake your head, there is definitely a lot of real red meat in this book and letting it nourish you will indeed be worth your time. Some may complain that the advice is a little cynical in spots, or that they would never do the things that Jerry advocates, or that some of it comes across as unprofessional. To those people, I would suggest that they take themselves out of the equation for a minute, and examine human behavior. Jerry's examples and laws are not cynical, they are human, and they map to the way that people actually behave and interact with each other. Jerry's Laws are universal. The political, social, and behavioral problems we face tend to likewise be universal.


Most of all, this book is for every consultant out there, not just the ones that have that title tacked on their business cards and letterheads. When we get right down to it, every one of us is a consultant. We offer a service to our clients, and every law that Jerry espouses works just as well for us workaday employees as it does for official consultants. At some point in our careers each of us is going to need to be the bringer of news that others will not want to hear. How we deliver that news most effectively ultimately is up to us, but with these handy rules in mind, we can be more effective in sharing that news.


Bottom Line:

Don't think that because you are not an officially titled "Consultant" that this book will serve no purpose or have no value for you. In fact, I'd suggest everyone take a little piece of masking tape and cover up the word "Consulting" and write down "Dealing with Other People, Period". See, that way, when you reach for a copy of "the Secrets of Dealing with Other People, Period" then all of the story's, rules, limits, and laws will make much more sense, and their ready applicability to *everyone* can be better appreciated. I've seen many people say that this book is one they read over and over. I can certainly understand why.

Tuesday, February 7, 2012

Book Review: Head First HTML5 Programming


It’s a good bet that at some point your everyday tester is going to need to come face to face with the newest web standards, and if you have to get exposed to it from a books viewpoint, well, this is a friendly and straightforward way to do it. Head First HTML5 Programming uses a fun and graphically dense format to help get people comfortable with the ideas of using HTML5, CSS3 and Javascript.

OK, first and foremost, this is not an absolute beginner’s book, although you may well find that you don’t need all that much underlying understanding to be effective. If you have a basic understanding of HTML tags understand some CSS formatting and have seen and can recognize XHTML or XML, then you know enough to work through this book. This is also not a grans master’s book, either. It is not a comprehensive reference. What it does do is provide a basic framework and some fun text to help the user get familiar with HTML5 syntax and use JavaScript to help create web applications.

The book starts out with some basics, showing you how HTML5 is utilizing the standards of HTML, CSS and JavaScript as defaults, and the fact that many of the strict type details that were part of HTML 4.01 and XHTML are integrated.  Games such as crossword puzzles, word matches, sample programs and workbook projects are included to help get the gist of how to use recognize the changes and see them in action. Interviews with HTML5 and JavaScript are also included (no, I didn’t just make that up :) ).

The book then moves into JavaScript and explains the way JavaScript works, including a syntax run down, how to use it in simple programs, as well as how to put the scripts into web pages, and explains the Document Object Model (DOM) that is created and used to enact your JavaScript.

Creating event handlers and interactive controls to a user is up next. By making a simple song selector, the user is shown how to make buttons and tie events to them, , along with creating new elements to hold information and display songs. The exercises help the user see how the code and page elements interact with each other.

Functions and objects are next on the list. Chaining, constructors, and scope, oh my.

Geolocation gets a chapter, meaning that we can make our pages and our code pieces  location aware (by using the Geolocation JavaScript API). This can be done at a GPS level or an IP address level, but in both cases, this chapter covers ways to say where you actually are.

Web Services gets a chapter and a look at XMLHttpRequest, JSON, and JSONP, and shows when to use which, and how to fetch data at regular intervals to update the application you make (and with gumballs, no less).

The Canvas chapter explains how to use the canvas element to physically draw out parts of the page. With a T-shirt design problem, we create a square, manipulate the pixels to create fills, fail gracefully and inform users if their browsers are too old to support canvas, and create functions to draw circles and other shapes. Creative text can be displayed as well.

The Video tool allows developers to not just embed video in pages, there’s also playback, moving forward and backwards, handling different video formats, and embedding video images into objects that you have drawn onto the canvas tool. We also get to play with a variety of video formats including H.264, VP8 and Theora. Video also allows the user to use an API to focus on a variety of behavior.

Web storage, or more commonly, localStorage, gets coverage and an explanation of how it differs from traditional “cookies”. Starting with the space (cookies max out at 4kB, localStorage gives you 5MB for each domain).

The book rounds out with the topic of Web Helpers, the ability to spawn small JavaScript threads to take over the lengthier or more involved processes, so that the browser doesn’t wait forever for that particular process to finish (with an explanation of an exploration of Mandelbrot Sets just for fun).

There are also a number of topics that didn’t get covered, such as Modernizr, Audio, jQuery, XHTML, SVG, Offline Web Apps, Web Sockets, more advanced Canvas API, Selectors API, and many other things that would make a book already 600 pages much thicker (especially since most pages are graphically structured with examples, puzzles and a lot of pictures).


Bottom Line: 


It’s cutesey, it’s kitschy, it’s loaded with pictures, diagrams, and other stuff that may drive some people crazy (the “get to the point already” people), and I’d say that, for those people, they are probably already knowledgable enough to go beyond what this book offers anyway. If, however, you are like me, and don’t necessarily mind a variety of presentation options, and the “ooh shiny” quotient is high, and the need to have silly asides and corny jokes abound to keep you smiling, and engaged, then I have to say there’s a lot to like here.

Monday, February 6, 2012

Exploring Black Box Machines

On Saturday, I had the chance to step back and be a participant again for Weekend Testing. Albert developed and ran the session this time, and frankly, I think it was one of the best ones we've had.

This session was called "Black Box Machine", and it was based around, you guessed it, testing a truly black box device. We really didn't have any idea what we had or what it did. It was a screen with a gauge, a red LED, a green LED, 4 blue buttons and 4 yellow buttons. Click on the experience report link above to see the machine layout we used.

The buttons were functional, and combinations of the buttons controlled the lights and the gauge.

I had a chance to work with and discuss the approach with Russ Poole, a newcomer to Weekend Testing. Often, we split into pairs for these sessions to do the actual testing, with an experienced Weekend tester working with someone who is new to the format, or a more experienced tester working with a less experienced tester. We took some time to acquaint ourselves with the machine and worked through the buttons to see what they did. Through exploration, trial and error and questioning, we made a mental model of what the device might be. We knew the mental model might be wrong, but it was useful for a time to help us describe what we were seeing, and use a common language between us. With this approach, we were able to divide and conquer the problem and determine what the machine did. Well, determine what we thought the machine did.

Each of the testers or pairs of testers did the same thing in the time frame we provided, and each group or individual presented their approach. It was interesting to see that each pair had a slightly different method to their testing and their vision of the problem. Each of us used heuristics to help us define the problem, and to come to some conclusions. I explained to Russ that our mental model may be correct, or it may not be. Still, as long as we kept learning about the product and could try out our ideas, we were able to determine at least on the surface what we thought the machine was doing.

This exercise is built on a number of examples that James Lyndsay developed, the entire purpose of these "machines" being to help people understand exploratory testing in a way that may get lost when working with known products. With everyday well known software applications, we can use some markers and guidelines to help us, and those familiar items and ideas will naturally guide how we test. Tthese machines are void of any natural context, and as such, we are basically left to our own deductive and inductive reasoning to figure out what's going on.

Again, I think this was a fantastic session. My thanks to Albert Gareev for facilitating it, and my thanks to all of the participants for taking the time to come out and play with us on Saturday.

Thursday, February 2, 2012

Online Summit: Agile Transitions


It looks like 2012 is shaping up to be a series of first for me. to that column I can now add "will present to an online forum a webinar/talk". How and when will I be doing that, you say?


I will be presenting at the SoftwareTestPro Online Summit for "Agile Transitions".


I've had to go through my own "cultural shift" the past year as I've made my transition away from being a software tester in a traditional testing organization to being a tester embedded into an Agile team. My goal is to share some of my own experiences, pitfalls, adjustments and lessons learned, as well as to offer some tips specifically for Lone Testers who are finding themselves embedded in Agile teams, or interested in making the transition.

The Online Summit will be held from Tuesday February 21 10:00AM until  Thursday February 23 1:30PM PST (each of the summit times will be three hours during that time period). The schedule is listed below (at least the schedule as it stands right now). My session is highlighted :).

The cost of the summit is $195USD if you sign up before 2/14/12, it will be $245USD after that.


Scott Barber will be hosting this online summit, and he has gathered a number of different speakers to present on various topics. I will be speaking on the topic of being a Lone Tester making the transition to Agile.

The cool thing about this approach... you don't have to travel. Depending on your work arrangements, you may not even have to block out any specific time. These courses are each about an hour long and only cover three hours each day. The audio and video from each session will be recorded. If you miss a session, you will have access to all of the session recordings once the summit has ended.


The schedule as it currently stands is a follows:

Tuesday February 21, 2012

10:00- 10:10 AM PT Welcome, Overview and Agenda

10:15-11:15 AM PT What is Agile and What's it Got to do With Testing?
– Scott Barber

11:10-11:20 AM PT Break

11:25-12:25 PM PT How "Agilists" vs. "Traditionalists" View Testing
– Robert Walsh

12:20-12:30 PM PT Break

12:30-1:30 PM PT Keys to Transitioning to Agile Testing: Lessons Learned from the Trenches
– Bob Galen


Wednesday February 22, 2012

10:00- 10:05 AM PT Day 2 Welcome and Agenda

10:05-11:05 AM PT The Secret to Successful Agile Test Automation
– Lisa Crispin

11:05-11:15 AM PT Break

11:15-12:15 PM PT Culture & Inter-Focus Area Interactions
– Selena Delesie

12:15-12:25 PM PT Break

12:25-1:25 PM PT Avoiding Agile Perversion
– Lanette Creamer

1:25-1:30 PM PT
 Day 2 Summary and Closing Thoughts


Thursday February 23, 2012

10:00- 10:05 AM PT Day 3 Welcome and Agenda

10:05-11:05 AM PT Excelling as an Agile Tester
– Henrik Andersson

11:05-11:15 AM PT Break

11:15-12:15 PM PT      The Lone Tester in an Agile World
– Michael Larsen

12:15-12:25 PM PT Break

12:25-1:25 PM PT 10 Tips for Agile Transitions & Panel Discussion
– Scott Barber & Panel

1:25-1:30 PM PT
 Day 3 Summary and Closing Thoughts


 Here's hoping I will see some of you there :).

Tuesday, January 31, 2012

Exercise 51: Getting Input From A Browser: Learn Ruby the Hard Way: Practicum

All right, so we have a simple Sinatra framework up and running. Now let's see if we can do something just a little more exciting, shall we :)?


This time around, we'll make some interactive elements. We will submit text to our application by using that well known method, the form. Additionally, we'll look at ways that we can do automated testing for forms.




How The Web Works (The Boring Bits)




Zed's got this pretty well nailed down, so I'll let him tell this part :):

- You type in the url http://learnpythonthehardway.org/ into your browser and it sends the request out on line (A) to your computer's network interface.


- Your request goes out over the internet on line (B) and then to the remote computer on line (C) where my server accepts the request.


- Once my computer accepts it, my web application gets it on line (D), and my web application code runs the / (index) handler.


- The response comes out of my web server when I return it, and goes back to your browser over line (D) again.


- The server running this site takes the response off line (D) then sends it back over the internet on line (C).


- The response from the server then comes off the internet on line (B), and your computer's network interface hands it to your browser on line (A).


- Finally, your browser then displays the response.

Rather than go through a full breakdown of what the web terms mean, I'll let the reader take a look at Zed's very well done crash course explanation over at http://ruby.learncodethehardway.org/book/ex51.html (chances are, if you've gotten this far with me, you already know the links and site very well.

How Forms Work

Let's take the lib/gothonweb.rb file make some changes to it:


- Restart Sinatra (hit CTRL-C and then run it again) to make sure it loads again



- With your browser go to http://localhost:4567/hello which should display, "I just wanted to say Hello, Nobody."



- Next, change the URL in your browser to http://localhost:4567/hello?name=Frank and you'll see it say "Hello, Frank."



Finally, change the name=Frank part to be your name. Now it's saying hello to you.



So what have we done here?


- We're now using the "params" hash with a value of ":name" to get data from the browser. Sinatra takes all of the key/value pairs after the ? part of the URL and adds them to the params hash for you to work with.

- The greeting is then constructed from the value of ":name". By default we set this to "Nobody". If we give it a name value on the command line, it changes it based on the "name=EnteredName" that we put in the URL after the "?"

We can add more than one param on the command line, too if we modify the script to accept the changes.


We can change the code to get params[:name] and params[:greet] as well like this:



By default, it looks like this:



And with the url values, it looks like this:

Example:
http://localhost:4567/hello?greet=Wassup&name=Michael




Creating HTML Forms


OK, so we can pass the values through the URL, but let's face it, that's a pain. Most people expect to enter information in the browser directly and hit a button. this uses the time honored web feature called a form (or a POST form, to be more specific). A form is just an HTML file with a "form" tag in it. This form will collect information from the user, then send it to your web application just like you did above.

Let's make a quick form to see how this works (this is being done in  lib/views/hello_form.erb):


Now make some changes to gothonweb to be able to accept the form:


Once you've got those written up, simply restart the web application again and hit it with your browser like before.




The part of the hello_form.erb file that makes this work is the line with
. This tells your browser to:

- Collect data from the user using the form fields inside the form.

- Send them to the server using a POST type of request, which is just another browser request that "hides" the form fields.

- Send that to the /hello URL (as shown in the action="/hello" part).


Creating A Layout Template

For the final exercise, we'll be making a bunch of small HTML pages. Having to always code up a page each time will soon become tedious, so we'll create a simple "layout" template to wrap all of our pages with common headers and footers.

So here's the change to lib/views/index.erb:



Change lib/views/hello_form.erb to be like this:



This removes all of the general "boilerplate stuff" that every page will have at the top and the bottom, and now we'll make a layout page that contains all of that:

Here's lib/views/layout.erb file that handles it for us from now on.

Once you have those changes, create a lib/views/layout.erb file with this in it:




Writing Automated Tests For Forms

So now that we have made these changes, we could keep loading up the web page each time to see if we have made the correct changes... or we could use our unit tests to see if what we have put in works, too. The tester in me would like to see us do both, so lets do that :).

Create the file test/test_gothonweb.rb with these contents:



Finally, run test/test_gothonweb.rb to test your web application:

$ ruby test/test_gothonweb.rb
Loaded suite test/test_gothonweb
Started
.
Finished in 0.023839 seconds.


1 tests, 9 assertions, 0 failures, 0 errors, 0 skips


Test run options: --seed 57414

Note: what's being seen here is not what I am seeing. Maybe there is a step missing, but the framework appears to be running as expected. Again, it's a problem I'l tweak a bit more later.

Zed explains that what is happening here is that we're importing the whole application from the lib/gothonweb.rb library, then running it manually.

The rack/test library we have included has a very simple API for processing requests. Its get, put, post, delete, and head methods simulate the respective type of request on the application.

- All mock request methods have the same argument signature:

get '/path', params={}, rack_env={}

- /path is the request path and may optionally include a query string.

- params is a Hash of query/post parameters, a String request body, or nil.

- rack_env is a Hash of Rack environment values. This can be used to set request headers and other request related information, such as session data.

This works without running an actual web server so you can do tests with automated tests and also use your browser to test a running server.

To validate responses from this function, use the assert_response function from test/test_gothonweb.rb which has:

assert_response(resp, contains=nil, matches=nil, headers=nil, status=200)


TESTHEAD's TAKEAWAYS:

This is pretty cool, again, this helps make a lot more sense out of what I've been seeing in the code and the rails applications that I use (the boilerplate loading up the header and the footer that's the same, and then the specific code elements being loaded as needed and only when needed, it's a beautiful thing. The Unit tests are not behaving the way that I expect them, to, but again, it's possible I'm missing something or I configured something wrong. Even without this specific aspect, I think the point has been made. Sinatra makes for an elegant little framework for running a server.

Monday, January 30, 2012

Exercise 50: Your First Website: Learn Ruby the Hard Way: Practicum

Cool, we have finally reached the point where we interact with the web and web components using Ruby.


The example text uses the Sinatra framework.


Having heard of Sinatra in various places, I've been interested in seeing how to interact with it (and see how it differs from Rails, which is an environment I already use and test in my "day job" :).


Installing Sinatra


Using gem install Sinatra:



Make A Simple "Hello World" Project


Now you're going to make an initial very simple "Hello World" web application and project directory using Sinatra. First, make your project directory, and then create the structure by running "bundle gem gothanweb (gothan being the game we've been working with for the past while):

Now let's make a very basic Sinatra application by putting the following code into lib/gothonweb.rb:
Then run the application like this:


Finally, use your web browser and go to the URL http://localhost:4567/.

Well, this is what I see:



What's Going On?

Here's what's happening when your browser hits your application:

- The browser makes a network connection to your own computer on port 4567.

- Once it connects, it makes an HTTP request to the lib/gothonweb.rb application and asks for the / URL, which is commonly the first URL on any website.

- Inside lib/gothonweb.rb there are blocks of code that map to URLs. The only one we have is the '/' mapping.

- Sinatra calls the matching block, which simply returns a string for what Sinatra should send to the browser.

- Finally, Sinatra has handled the request and sends this response to the browser which is what you are seeing.


Fixing Errors

Comment out line 6 where you assign the greeting variable, then hit refresh in your browser. 



You should see an error page now that gives you lots of information on how your application just exploded. You know that the variable greeting is now missing, but Sinatra gives you this nice error page to track down exactly where. Do each of the following with this page:

- Look at the sinatra.error variable.

- Look at the REQUEST_ variables and see if they match anything you're already familiar with. 

- Uncomment line 6 and all returns back to normal.





Create Basic Templates





The following steps will make a properly formed "web page". This page used the embedded ruby extension [filename.erb]. It's stored in lib/views.

The first step is to create a lib/views/index.erb file that looks like this:
Now we modifying the lib/gothonweb.rb script, so that Sinatra has a way to access the ERB file:


So what happens if we reload the web page with these changes?

And just to show that it's properly formsed HTML...:
So what's going on here?

- In lib/gothonweb.rb we added an erb method call.

- The erb method loads .erb files out of the lib/views/ directory. We pass it index.erb because we're passing that as a parameter (erb :index ...).

- Now, when the browser hits / and lib/gothonweb.rb matches and executes the get '/' do block, instead of just returning the string greeting, it calls erb and pass greeting to it as a variable.

- Finally, the HTML in lib/views/index.erb contains Ruby code that tests the greeting variable, and prints a message using the greeting.


TESTHEAD's TAKEAWAYS:

So this is a very simple and basic example, but it shows that we can fairly quickly develop a web site within a framework and use Ruby to pass variables for the values it would expect to see. That's pretty cool :).