Dedicated to Ashley & Iris

НазваниеDedicated to Ashley & Iris
Размер3.51 Mb.
1   ...   63   64   65   66   67   68   69   70   71

Test Integration

One button must test all aspects of every module, and one top-level AllTests command must test all modules. Our survey of techniques here challenges rambunctious web projects to minimize their language diversity. Ideally, only one language should host all tests. But our survey showed how different web layers can require tests in different languages.

Tests written in Ruby, for example, could shell to JavaScript (hosted in ksjcmd) to run a few DOM tests, and collect their return value to “bubble up” their status:

result = system("kjscmd myDomTests.js")

assert_equal(0, result)

The patterns of failures in these “shelled tests”, and their interactions with your editors, will reveal when and how to improve their Fault Navigation.

When you change a test, get it to fail, change the source, and get it to pass, each test run must be as easy as a few keystrokes—hopefully just one. That’s why you must spend a little extra effort to cobble together scripts and embedded command lines to put all these different test rigs, on both the server and client side, under one of your editor's buttons.

Ideally, a project that limits client-side JavaScript will require only a few DOM tests.

Before introducing our main project, I’m compelled to showcase a fine example of a test-first project that exploits advanced client-side JavaScript.

Remote User Interface

This light GUI Toolkit—written & tested in Perl, Java & JavaScript by Ran Eliam and hosted at—is a magnificent example of these solutions:

  • TFUI, with tests on both the server and client

  • Duplication between the server and client resolved

  • Seamless client-side experience, without fetching pages for each click

  • Client-side controls via Model View Controller.

TODO Please read its entire Web site and source; it fits this , and insert all of that content here.

A pretty picture:

TODO My white arrow indicates the user’s mouse pointer forming a double-headed arrow over a splitter bar. All this behavior runs client-side, in a Web browser!

A product that stretches languages’ abilities so far (Perl to serve Web pages, JavaScript to paint controls, etc.) is often too fragile. But tests keep this product robust.

The only downside is the product requires Internet Explorer 6. In theory, to port to another browser, one need only get all the JavaScript tests to pass.

To illustrate Web testing, we will select a project with a slightly thinner client.

Mini Ruby Wiki

Unlike other Case Studies, this one cannot invite the reader to play along with the text, and make each change as presented. You have already learned the TFUI Principles for simpler projects; the project here must cover too much territory for each little refactor to provide readable prose.

Wiki Wiki Web sites present a range of test challenges. If you never heard of a Wiki, stop reading now and e-search the Internet for “WikiWikiWeb”. Ward Cunningham invented them, and co-wrote The Wiki Way: Collaboration and Sharing on the Internet, with Bo Leuf.

Some day there will be as many versions of Web sites with content that users can edit as there are Linux distributions. Their divergent features target various intents and whims. For example, my latest Wiki, called MiniRubyWiki (MRW), is written in Ruby, produces XHTML, and can display GraphViz output. (Try to survive those shocks!)

Wiki Wiki Webs

Humans, collaborating to write a Web site, most frequently want to upload simple paragraphs of text, containing a few markup codes and links to other pages in the same site.

The least simple solution gives all the users expensive “WYSIWYG” editors and complex upload protocols. The most simple solution gives each Web page an “EditPage” button. When you click it, you get a page containing the previous page’s content area rendered as a big edit field. The content area contains not HTML source but a tiny breezy markup language:

Analyzing users’ requirements, removing duplication from their behaviors, and trimming unneeded features all specify the simplest thing that could possibly work: A Wiki.

Duplication removal drives design. Source should strive to define program behavior Once and Only Once. Software should not require users to perform the same sequence of actions too often. So duplication removal drives requirements analysis.

Wiki Markup

Here are the two most common Wiki typesetting markups, using ticks ', with their outputs seen through default browser settings:

this is ''em''phatic—this is emphatic

this is '''strong'''—this is strong

All Wikis provide a few more complex markups. But Wiki notation obeys constraints different from other authoring systems. HTML strictly reserves the tag marker <>—nothing else may resemble one. But Wiki markup obeys naïve users’ understanding, and advanced users’ expedience, over strict markup purity. A single tick ' is just an apostrophe. Wikis cannot indulge in arbitrarily complex markups. Many simply provide an “HTML Mode” for select pages, giving power-users free reign. And many reserve a special character at the start of a line, such as a bang !, to escape embedded commands.

External Links

Wikis express URLs, such as, or, as hypertext links to their targets. When such URLs begin with http: and end with a common graphics file extension, such as .gif, .jpg, or .png, Wikis instead display them using the command. To decorate a Wiki with graphic content, put graphic files on a web server, and enter their addresses into your page.

Internal Links

The absolute genius of the original Wiki, honored in all its followers, is its internal link protocol. A word with leading and embedded capital letters, such as WardCunningham, renders a link to the nearest Wiki page with that name. Users create a growing KnowledgeBase full of project details, written on pages named using ProjectSpecificJargon.

Teams should deliberately create such jargon (their SystemMetaphor) and store it in their KnowledgeBase Wiki.

The reader indulges in the original meaning of “hyper” text—they can read a page from top to bottom, or they can read in the orthogonal dimension; out and back through other pages.

When Representation Layers Produce HTML

The core of every Wiki is a Representation Layer that converts Wiki markup into an HTML representation. MRW developed test-first. Its earliest features (with highest business value) transform one representation (the Wiki markup) into another (HTML).

These primordial assertions, for example, created and defended the Wiki markup:

"), "<br>\n")

assertEqLf(formatWiki("''br''"), "br\n")

assertEqLf(formatWiki("Yo"), "Yo\n")

assertEqLf(formatWiki("YoYo"), "YoYo?\n")

got = formatWiki('FrontPage') # a ‘tag’, or internal link

assert_match(/href="FrontPage/, got)

got = formatWiki('baBaLoo') # not a tag

assert_no_match(/href/, got)

got = formatWiki('WinThirty2') # not a tag either

assert_no_match(/href/, got)

(assertEqLf() Fuzzily Matches HTML, disregarding many blank characters.)

Bulk Parsed Fuzzy Matches

Because MRW produces XHTML, one can test-last entire pages using validating parsers.

Validating HTML parsers make respectable tests. We prefer XHTML because XPath can incidentally validate as it queries contents. Many other fine validators are available. When they leverage awareness of HTML structure, they can detect errors in the meaning of the markup tags. For example, one should not put a tag inside a <body> tag. <br /> <br />The program Tidy, by Dave Raggett, can read HTML and return a list of these issues. Get it at<br /> <br />MiniRubyWiki used Tidy, early in its development, to constrain its HTML output. The case test_tidyDoesNotDespiseOurHTML() converts each page in a list from Wiki format into HTML, passes this through Tidy, and parses the extracted error messages. For any non-trivial error, the test case prints out the offending HTML line, with a caret ^ pointing at the beginning of the offending codes.<br /> <br />This system does wonders to constrain refactors so they strictly preserve behavior. The user, and their browser, might not care if a given stretch of HTML said:<br /><br /><br /><b><em>so what?</b></em><br /> <br />or:<br /> <br /><b><em>so what?<b></em></b></b><br /><br /><br />Honestly, we still don’t care either. But if a refactor accidentally inverted those two end tags, it could invert other things, too. Tidy will stop us as soon as possible, and print out the line that failed. We will (usually) ignore the error message, tap Undo until it goes away, and try again. <br /> <br />Hyperactive tests are good because they prevent sloppy refactors. A hyperactive test fails when a user would not have perceived a bug. TFP produces many such tests, because over-constraining is cheaper than exactly constraining. When such a test fails, only the most recent edit could be at fault. If a module leverages such tests, ensure they run with its tests, not with the integration tests.<br /> <br />Pouring an entire page into a validator might be called a “bulk assertion”. Use such techniques aggressively, but watch out for two problems.<br /> <br />If we don’t ignore the error message, it does not directly indicate which line of source code caused the problem. The validator will reveal the line of XHTML that offended it, not the line of your source that caused the error. The error messages, and your test case’s diagnostic output statements around them, provide plenty of clues, but no smoking gun. Most of our tests approach the ability of a <b>Unit Test</b> to isolate our culprits.<br /> <br />Bulk assertions’ biggest problem is they can’t test-first. Validators that rely on HTML that already exists can’t enforce new features.<br /> <h2><a name="_ref78881062"></a> Custom Controls</h2> <br />We will add to MRW some features more advanced than <form> and <textarea>. Diverse code, in several layers, support their behaviors, so each layer needs new kinds of tests. And some tests will target the wrong layer simply to prove we can write a test in a difficult situation.<br /> <h3>Transclusion</h3> <br />“Transclude” means “transitive include”. Our Wiki will go beyond passive inclusion of read-only material. We will add features to our Wiki that allow users to read and write formatted data, and execute programs with them.<br /> <br />Our Customer Team wants us to add new markup commands to Wiki page source that produce interactive controls. Some will provide client-side JavaScript, so we will soon need tests on that behavior. Those tests will need a fixture that drives Internet Explorer’s DOM through its automation interface, so we will find an early excuse to write one.<br /> <br />The feature requests:<br /><br /><ul> <li><br /> Wiki pages can <b>Transclude</b> text files as <textarea> tags.<br /> <li><br /> A “<b>Save</b>” button shall save changes.<br /> <li><br /> Users can <b>clone</b> the text file to a new name.<br /> <li><br /> Cloned files appear <b>next</b> in the Wiki page.<br /> <li><br /> A “<b>Test</b>” button can save the text file, then send its name to a console program.<br /> <li><br /> The <b>output</b> of the console program appears, formatted, below the <textarea>.<br /> <li><br /> Wiki pages can transclude simple <b>XML</b>.<br /> <li><br /> The XML shall <b>render</b> as HTML.<br /> <li><br /> The HTML shall display <b>edit fields</b> for attributes, and a <textarea> for the content.<br /> <li><br /> Each node has a “<b>Clone</b>” button, which clones the node.<br /> <li><br /> Each node has a <b>Test</b> button, which sends the node’s XPath and file name to a command.<br /> </ul> <br /><br />All these activities—saving files, executing commands, etc.—run server-side. Don’t expose MRW to the open Internet without further security precautions!<br /> <h3><a name="_ref75596187"></a> Transclude a Text File</h3> <br />The first decision: How to write a Wiki page that commands the Wiki format system to transclude a text file? Wikis display image files based on their extensions, but we will need more flexibility. Not all text files end in .txt.<br /> <br />Wikis often introduce their extension commands with a bang ! in the first column. English grammar forbids exclamation points to start sentences, so this operator is free to “overload”.<br /> <br />We might transclude a text file using only a bang and the file name:<br /><br /><br />!files/sample.txt<br /><br /><br />(We put the text files into a folder called “files”, to keep them out of the Wiki’s home folder.)<br /> <br />But peeking ahead at the requirements, we know we’ll introduce more commands than just text transclusion, so we follow the bang with the command text!, then a test fixture ruby -v!, then a folder and file name:<br /><br /><br />!<b>text!ruby -v!</b>files/sample.txt<br /><br /><br />Those learning Agile techniques may have heard one never writes speculative code. It’s true; the path from speculative code to code that adds value is always higher risk than the path from no code. However, if you peek ahead at requirements within this iteration, you might make a decision now that results in code just as simple as code written without peeking. You may speculate, just a little, so long as the current feature receives the same <i>volume</i> of behavior. If you guess wrong, the fix is always easy, because the speculation should not exceed the current iteration.<br /> <br />We’ll develop the <textarea> by testing the Representation Layer:<br /><br /><br />def test_transcludeText()<br /> <br /> hello_world = "hello world"<br /> <br /> writeFile("files/sample.txt", hello_world)<br /> <br /> transcluder = "!text!ruby -v!files/sample.txt"<br /><br /><br />contents = formatWikiTest(transcluder) <br /> <br /> assert_no_match(/#{transcluder}/, contents)<br /><br /><br /><span lang="">xhtml = "<BODY>" + contents + "</body></textarea></textarea></textarea></textarea></textarea></form></body>
1   ...   63   64   65   66   67   68   69   70   71


Dedicated to Ashley & Iris iconDedicated to Ashley & Iris

Dedicated to Ashley & Iris iconAbramovitz, Janet N., and Ashley T. Mattoon. 1999

Dedicated to Ashley & Iris iconPlastics and the Environment. Hoboken. N. J. Wiley-Interscience. Ashley, S. 2002

Dedicated to Ashley & Iris iconGilliland home is dedicated

Dedicated to Ashley & Iris iconCitations Acknowledging or using iris-related facilities and Data As of August 2010 Please send corrections and/or additions to

Dedicated to Ashley & Iris iconDedicated to Jerry Lefcourt, Lawyer and Brother

Dedicated to Ashley & Iris iconFree to download magazine dedicated to Commodore computers

Dedicated to Ashley & Iris iconMorning session I: Dedicated to Prof. A. Acrivos, “Suspensions and particulates”

Dedicated to Ashley & Iris icon08: 30 Registration 09: 00 Welcome Remarks Morning session I: Dedicated to Prof. A. Acrivos, “Suspensions and particulates”

Dedicated to Ashley & Iris iconThe Culture of Irises in the United States Iris Culture for the Mountain and Plains Region, D. M. Andrews 5

Разместите кнопку на своём сайте:

База данных защищена авторским правом © 2014
обратиться к администрации
Главная страница