This is your one stop shop introduction to get oriented to the world of reactive programming. There are lots of such intros out there even manifestos. We hope this is the one where you don't get lost and it makes sense. Get a definition of what "reactive" means and why it matters. Learn about Reactive Streams and Reactive Extensions and the emerging ecosystem around them. Get a sense for what going reactive means for the programming model. See lots of hands-on demos introducing the basic concepts in composition libraries using RxJava and Reactor.
This is your one stop shop introduction to get oriented to the world of reactive programming. There are lots of such intros out there even manifestos. We hope this is the one where you don't get lost and it makes sense. Get a definition of what "reactive" means and why it matters. Learn about Reactive Streams and Reactive Extensions and the emerging ecosystem around them. Get a sense for what going reactive means for the programming model. See lots of hands-on demos introducing the basic concepts in composition libraries using RxJava and Reactor.
PhoneGap Training - Optimus Prime
"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity."
— W.A. Wulf
I built an application and made this presentation for a class of mine. I wanted to demonstrate how easy Google App Inventor can be to use in building personal apps as well as introducing others to the world of application programing. Your comments and questions are very welcome!
[Srijan Wednesday Webinar] Mastering Mobile Test Automation with AppiumSrijan Technologies
Speaker: Justin Ison
Check out the complete session slides here: http://www.srijan.net/webinar/mobile-...
This session dives into the history of Appium, and it's pros and cons. The speaker also looks at how to write a good test setup and collect meaningful data points. We look at quick demos and comparisons of how Appium significantly reduces test times.
And you definitely should hang around till the Q&A session, where participants pitch in with their issues and queries. The speaker answers all the questions, sharing additional information and tips on Appium.
A presentation held at the JavaZone conference in Oslo, 2008 describing the iLabs Mobile Toolbox, a library for making Java ME applications without intolerable pain.
“What should I work on next?” Code metrics can help you answer that question. They can single out sections of your code that are likely to contain bugs. They can help you get a toehold on a legacy system that’s poorly covered by tests.
At a previous JRubyConf, we talked about Thnad, a fictional programming language. Thnad served as a vehicle to explore the joy of building a compiler using JRuby, BiteScript, Parslet, and other tools. Now, Thnad is back with a second runtime: Rubinius. Come see the Rubinius environment through JRuby eyes. Together, we'll see how to grapple with multiple instruction sets and juggle contexts without going cross-eyed.
PhoneGap Training - Optimus Prime
"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity."
— W.A. Wulf
I built an application and made this presentation for a class of mine. I wanted to demonstrate how easy Google App Inventor can be to use in building personal apps as well as introducing others to the world of application programing. Your comments and questions are very welcome!
[Srijan Wednesday Webinar] Mastering Mobile Test Automation with AppiumSrijan Technologies
Speaker: Justin Ison
Check out the complete session slides here: http://www.srijan.net/webinar/mobile-...
This session dives into the history of Appium, and it's pros and cons. The speaker also looks at how to write a good test setup and collect meaningful data points. We look at quick demos and comparisons of how Appium significantly reduces test times.
And you definitely should hang around till the Q&A session, where participants pitch in with their issues and queries. The speaker answers all the questions, sharing additional information and tips on Appium.
A presentation held at the JavaZone conference in Oslo, 2008 describing the iLabs Mobile Toolbox, a library for making Java ME applications without intolerable pain.
“What should I work on next?” Code metrics can help you answer that question. They can single out sections of your code that are likely to contain bugs. They can help you get a toehold on a legacy system that’s poorly covered by tests.
At a previous JRubyConf, we talked about Thnad, a fictional programming language. Thnad served as a vehicle to explore the joy of building a compiler using JRuby, BiteScript, Parslet, and other tools. Now, Thnad is back with a second runtime: Rubinius. Come see the Rubinius environment through JRuby eyes. Together, we'll see how to grapple with multiple instruction sets and juggle contexts without going cross-eyed.
In the 1980s, my grandfather reached onto the bookshelves of his cigar-smoke-seasoned garage laboratory and pulled down a three-ring binder that would change my life. Come hear how a 50-year-old introduction to binary logic has managed to stay relevant after all these decades, and what it means for our own efforts to teach and document technical subjects.
JRuby, Not Just For Hard-Headed Pragmatists AnymoreErin Dees
JRuby bills itself as the pragmatic Ruby, the go-to implementation when you need to fit into the Java universe or support a ton of platforms.
Who knew it was also a tool for having fun exploring the realms of computer science?
This talk discusses ways to keep work playful (and as a side effect do better work), including:
* Dealing with crusty data formats and protocols in a lighthearted way
* Scripting other people’s software (whether they know it or not)
* Sharing your code with co-workers without annoying them
* Deploying your programs to honest-to-goodness paying customers
How 5 people with 4 day jobs in 3 time zones enjoyed 2 years writing 1 bookErin Dees
The story of writing the JRuby book together, with lessons for freelancers, telecommuters, and remote collaborators everywhere. Speaker notes from Open Source Bridge 2011.
How 5 people with 4 day jobs in 3 time zones enjoyed 2 years writing 1 bookErin Dees
The story of writing the JRuby book together, with lessons for freelancers, telecommuters, and remote collaborators everywhere. Slides from Open Source Bridge 2011.
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
The IoT and OT threat landscape report has been prepared by the Threat Research Team at Sectrio using data from Sectrio, cyber threat intelligence farming facilities spread across over 85 cities around the world. In addition, Sectrio also runs AI-based advanced threat and payload engagement facilities that serve as sinks to attract and engage sophisticated threat actors, and newer malware including new variants and latent threats that are at an earlier stage of development.
The latest edition of the OT/ICS and IoT security Threat Landscape Report 2024 also covers:
State of global ICS asset and network exposure
Sectoral targets and attacks as well as the cost of ransom
Global APT activity, AI usage, actor and tactic profiles, and implications
Rise in volumes of AI-powered cyberattacks
Major cyber events in 2024
Malware and malicious payload trends
Cyberattack types and targets
Vulnerability exploit attempts on CVEs
Attacks on counties – USA
Expansion of bot farms – how, where, and why
In-depth analysis of the cyber threat landscape across North America, South America, Europe, APAC, and the Middle East
Why are attacks on smart factories rising?
Cyber risk predictions
Axis of attacks – Europe
Systemic attacks in the Middle East
Download the full report from here:
https://sectrio.com/resources/ot-threat-landscape-reports/sectrio-releases-ot-ics-and-iot-security-threat-landscape-report-2024/
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on the notifications, alerts, and approval requests using Slack for Bonterra Impact Management. The solutions covered in this webinar can also be deployed for Microsoft Teams.
Interested in deploying notification automations for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
JMeter webinar - integration with InfluxDB and GrafanaRTTS
Watch this recorded webinar about real-time monitoring of application performance. See how to integrate Apache JMeter, the open-source leader in performance testing, with InfluxDB, the open-source time-series database, and Grafana, the open-source analytics and visualization application.
In this webinar, we will review the benefits of leveraging InfluxDB and Grafana when executing load tests and demonstrate how these tools are used to visualize performance metrics.
Length: 30 minutes
Session Overview
-------------------------------------------
During this webinar, we will cover the following topics while demonstrating the integrations of JMeter, InfluxDB and Grafana:
- What out-of-the-box solutions are available for real-time monitoring JMeter tests?
- What are the benefits of integrating InfluxDB and Grafana into the load testing stack?
- Which features are provided by Grafana?
- Demonstration of InfluxDB and Grafana using a practice web application
To view the webinar recording, go to:
https://www.rttsweb.com/jmeter-integration-webinar
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
As AI technology is pushing into IT I was wondering myself, as an “infrastructure container kubernetes guy”, how get this fancy AI technology get managed from an infrastructure operational view? Is it possible to apply our lovely cloud native principals as well? What benefit’s both technologies could bring to each other?
Let me take this questions and provide you a short journey through existing deployment models and use cases for AI software. On practical examples, we discuss what cloud/on-premise strategy we may need for applying it to our own infrastructure to get it to work from an enterprise perspective. I want to give an overview about infrastructure requirements and technologies, what could be beneficial or limiting your AI use cases in an enterprise environment. An interactive Demo will give you some insides, what approaches I got already working for real.
Search and Society: Reimagining Information Access for Radical FuturesBhaskar Mitra
The field of Information retrieval (IR) is currently undergoing a transformative shift, at least partly due to the emerging applications of generative AI to information access. In this talk, we will deliberate on the sociotechnical implications of generative AI for information access. We will argue that there is both a critical necessity and an exciting opportunity for the IR community to re-center our research agendas on societal needs while dismantling the artificial separation between the work on fairness, accountability, transparency, and ethics in IR and the rest of IR research. Instead of adopting a reactionary strategy of trying to mitigate potential social harms from emerging technologies, the community should aim to proactively set the research agenda for the kinds of systems we should build inspired by diverse explicitly stated sociotechnical imaginaries. The sociotechnical imaginaries that underpin the design and development of information access technologies needs to be explicitly articulated, and we need to develop theories of change in context of these diverse perspectives. Our guiding future imaginaries must be informed by other academic fields, such as democratic theory and critical theory, and should be co-developed with social science scholars, legal scholars, civil rights and social justice activists, and artists, among others.
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Cucumber meets iPhone
1. meets iPhone
OSCON 2009
Ian Dees
http://www.ian.dees.name
Hi, everyone. Welcome to OSCON. This talk is about testing the GUIs of
iPhone apps using the Ruby language and the Cucumber test framework.
2. #osconcuke
First, a bit of business. Per Giles Bowkett, here’s a Twitter hashtag for
this talk. Throughout the presentation, audience members can tweet
their questions here. This will hopefully keep people from being put on
the spot, and will also provide a place to fill in any answers we don’t
have time for today.
3. p
Now, a bit about what I do—because you're no doubt deeply caring and
curious people, and because it will shed light on what we're doing here
today. I write software for Tektronix, makers of test equipment (though
this talk isn't about my day job). The interfaces we build involve things
like touch screens and physical knobs. Each style of interface demands
new ways of testing.
4. I’ve written a book that tells that kind of story—adapting tests to the
quirks and realities of a platform—in code.
5. ?
When a new platform comes out, be it a phone or a runtime or an OS, I
get curious: how do they test that? And that’s what led me to think
about the kinds of things I’m talking about today. So, on to our topic:
testing the iPhone with Cucumber.
7. LET’S GET U INTO
BEHAVIOUR-DRIVEN
DEVELOPMENT
Cucumber is a Behavio(u)r-Driven Development framework built on
Ruby. You write your top-level tests in a language suited for that task
(English). And you write your glue code in a language suited for that task
(Ruby).
8. FLAVOUR OF THE MONTH?
Flavor of the month? (Buzzword) bingo! BDD is indeed a flavor, a
seasoning, a heuristic which you use insofar as it helps you make sense
of your projects.
9. EXECUTABLE EXAMPLES
For the purposes of this talk, think of BDD as an appreciation of
executable examples. Early conversations about software projects tend
to take the form of examples and use cases; why not express them as
running code and have some smoke tests you can use later?
10. Ya gotta have a real project to throw your ideas against.
—Gus Tuberville (heavily paraphrased)
It’s all well and good to add a couple of token tests to a “Hello, world”
project. But it’s much more instructive to actually try to solve some real
problem.
11. QUESTION
“Oh crap, OSCON accepted my talk submission.
Now what do I do?”
So I looked for a real-world problem to solve.
12. QUESTION
“Can BDD be used to write an iPhone app?”
Something that wasn’t related specifically to this conference, or even to
the general task of seeing how well BDD and iPhone development fit
together.
13. QUESTION
“What’s on the radio?”
It had to be something I would have liked to do anyway, irrespective of
conferences and technologies. Something to keep the imagination
circuits grounded in reality.
14. JUST
PLAYED
http://www.25y26z.com
So I undertook to write an iPhone app that would let me “bookmark”
what radio station is playing any given moment and look the information
up later. Yes, I’ve heard of pencil and paper, Shazam, and the Zune.
There are tradeoffs that make this app better than those approaches in
some ways, and worse in others.
15. HOW THIN IS YOUR GUI?
Presenter First Technique—Brian Marick
http://exampler.com/src/mwrc-start.zip
Do you need a full-stack GUI test? If your GUI is an ultra-thin, ultra-
reliable layer on top of an API, many of your automated tests can bypass
the GUI and talk directly to the API.
16. DRIVING A GUI
1.Push the button
2.See what happens
At some point, though, it’s nice to see the real thing running, top to
bottom. And that’s the approach I took with the Just Played app.
The two main phases of automating a GUI are simulating events and
inspecting controls.
17. DRIVING THE PHONE
Matt Gallagher
http://cocoawithlove.com/2008/11/
automated-user-interface-testing-on.html
Matt Gallagher has done the groundbreaking work on both these fronts.
In a series of articles on his Cocoa With Love blog, he discusses how to
synthesize touch screen events and interrogate the GUI on an iPhone.
18. touchesBegan:withEvent:
touchesMoved:withEvent:
touchesEnded:withEvent:
Here’s how Matt’s technique works. When you tap a button on an
iPhone, the Cocoa Touch runtime looks at the button’s implementation
for these three methods and calls them in sequence...
22. WISH WE WERE HERE
UITouch *touch = [[[UITouch alloc] init] autorelease];
NSSet *touches = [NSSet setWithObject:touch];
UIEvent *event = [[[UIEvent alloc] init] autorelease];
[view touchesBegan:touches withEvent:event];
[view touchesEnded:touches withEvent:event];
So all we have to do is create the UITouch and UIEvent objects that the
functions expect to see, and all will be well, right? Except that Apple
didn’t provide initializers for these objects. And they have private fields
that have to be set up just so, or your app will crash.
23. CATEGORIES
@interface UITouch (Synthesize)
- (id)initInView:(UIView *)view;
- (void)setPhase:(UITouchPhase)phase;
- (void)setLocationInWindow:(CGPoint)location;
- (void)moveLocationInWindow;
@end
In Ruby, you’d write a monkey patch, modifying the vendor’s class at
runtime. Objective-C offers a slightly more civilized take on the concept,
called a category. You can add methods to a third-party class, and spell
out the scope in which they apply. Your new methods have access to the
class’s private fields; lucky for would-be GUI testers!
24. - (id)initInView:(UIView *)view
{
// ... code omitted for brevity ...
_tapCount = 1;
_locationInWindow =
CGPointMake(
frameInWindow.origin.x + 0.5 * frameInWindow.size.width,
frameInWindow.origin.y + 0.5 * frameInWindow.size.height);
_previousLocationInWindow = _locationInWindow;
UIView *target =
[view.window hitTest:_locationInWindow withEvent:nil];
_window = [view.window retain];
_view = [target retain];
_phase = UITouchPhaseBegan;
_touchFlags._firstTouchForView = 1;
_touchFlags._isTap = 1;
_timestamp = [NSDate timeIntervalSinceReferenceDate];
// ... code omitted for brevity ...
}
I gather this wasn’t easy. It probably involved making an educated
guess, reading the crash logs, trying to read Apple’s minds, making
some tweaks, and watching it crash all over again. Here are just some of
the private fields whose purposes, or at least required values, Matt was
able to divine.
25. DESCRIPTIONS
@interface UIView (XMLDescription)
- (NSString *) xmlDescriptionWithStringPadding:(NSString *)padding;
@end
// ---- snippet from implementation:
if ([self respondsToSelector:@selector(text)])
{
[resultingXML appendFormat:@"n%@t<text><![CDATA[%@]]></text>",
padding, [self performSelector:@selector(text)]];
}
The same technique—patching existing classes at runtime—works for
implementing the other half of the GUI testing equation. Here’s a
glimpse at how categories put a uniform face on runtime descriptions:
location, type, caption, and other information for every control on the
screen.
26. SCRIPT RUNNER
But how do you specify which button gets clicked, and when, and what
the expected outcome is? The original approach provides a ScriptRunner
object that reads in a list of commands from a text file.
27. BROMINE
(not the openqa one)
Felipe Barreto
http://bromine.googlecode.com
Matt’s original proof-of-concept embedded the test script inside a
special build of an app, which ran “headless”—working tests, but no GUI.
Felipe Barreto packaged up the code for running with a visible GUI, in
the simulator or on the iPhone. The project is called Bromine (as a nod
to the Selenium web testing tool), and is drop-in ready.
28. <plist version="1.0">
<array>
<dict>
<key>command</key>
<string>simulateTouch</string>
<key>viewXPath</key>
<string>//UIToolbarButton[1]</string>
</dict>
</array>
</plist>
The test script format for Bromine, like Matt’s project before it, is an
XML-based property file. It’s simple to parse from Cocoa Touch, but it
requires re-bundling your app every time you change your test script.
Also, adding conditional tests requires custom Objective-C code.
29. curl --url http://localhost:50000 -d
"<plist version="1.0">
<dict>
<key>command</key>
<string>simulateTouch</string>
<key>viewXPath</key>
<string>//UIToolbarButton[1]</string>
</dict>
</plist>"
So just for fun, I found an open-source Objective-C HTTP server,
dropped it into the project, and taught Bromine how to read its
commands from the server instead of a file. Now you can keep your app
running and drive it from curl.
30. require 'tagz'
command = Tagz.tagz do
plist_(:version => 1.0) do
dict_ do
key_ 'command'
string_ 'simulateTouch'
key_ 'viewXPath'
string_ '//UIToolbarButton[1]</string>'
end
end
end
Net::HTTP.post_quick
'http://localhost:50000/', command
Or Ruby.
31. BROMINE + NET = BROMINET
http://github.com/undees/brominet
I lightheartedly call the result “Brominet,” as a nod to the new-found
network connectivity (and because it’s missing a bunch of functions the
full Bromine library has).
32. COMPATIBILITY
2.2 3.0 3.1 3.2 beta
Simulator ✓ ✓ ✓ ✓
hope
iPhone ✓ ✓ ✓
so
One of the drawbacks of using categories to set private fields is that the
vendor might change those fields out from under you. Fortunately, the
Bromine project has volunteers who figure out how to stay on top of OS
changes. I’ve been porting their updates over to Brominet.
33. We’ve now got enough pieces to look at some of the test scripts for the
Just Played app, top to bottom.
34. story
step definition
ad-hoc API
GUI driver
The top-level user stories are in Cucumber’s test-oriented subset of
English. The Ruby code to press specific buttons is effectively an ad-hoc,
informally specified, bug-ridden API for the app. A layer of glue code—
step definitions—sits between them. Down in the plumbing, we make
angle brackets and post them via HTTP.
35. Feature: Stations
In order to keep my day interesting
As a radio listener with varied tastes
I want to track songs from many stations
Scenario: Deleting stations
Given a list of radio stations "KNRK,KOPB"
When I delete the first station
Then I should see the stations "KOPB"
s
Here’s a story from late in the app’s development. As with all the
features, I wrote the story first, and the feature later. The first few lines
are just commentary, imploring the test to justify its own existence.
36. Given a list of radio stations "KNRK,KOPB"
When I delete the first station
Then I should see the stations "KOPB"
s
The real heart of the tests are the Given/When/Then lines.
37. Given /^a list of radio stations "(.*)"$/
When /^I delete the first station$/
Then /^I should see the stations "(.*)"$/
d
Cucumber searches among the Ruby step definitions you’ve provided to
find the match for each step.
38. Given /^a list of radio stations "(.*)"$/ do
end
When /^I delete the first station$/ do
end
Then /^I should see the stations "(.*)"$/ do
end
d
When Cucumber hits a line of your test script, it runs the block of code
attached to the matching step definition. We could put HTTP POST
requests directly in these blocks.
39. Given /^a list of radio stations "(.*)"$/ do
|stations|
app.stations = stations.split(',')
end
When /^I delete the first station$/ do
app.delete_station(0)
end
Then /^I should see the stations "(.*)"$/ do
|text|
stations = text.split ','
app.stations.should == stations
end
d
But it’s often useful to wrap the specific button presses up in an
abstraction. Rather than say, “press the button whose caption is
‘Delete,’” you say, “delete something,” and rely on your ad-hoc API to
define how deleting happens in the GUI.
40. class JustPlayed
def stations=(list)
plist = Tagz.tagz do
array_ do
list.each {|station| string_ station}
end
end
@gui.command 'setTestData', :raw,
'stations', plist
end
end
end
a
Here are a few pieces of that API. First, for the Given step, we’re
bypassing the GUI and pre-loading the app with canned data. (In the
context of Rails apps, David Chelimsky calls this technique Direct Model
Access.) Brominet sees the “setTestData” command, recognizes it as
something not GUI-related, and hands it off to the app’s delegate class.
41. class JustPlayed
def delete_station(row)
@gui.command 'scrollToRow',
'viewXPath', '//UITableView',
'rowIndex', row
@gui.command 'simulateSwipe',
'viewXPath', "//UITableViewCell[#{row + 1}]"
@gui.command 'simulateTouch',
'viewXPath', '//UIRemoveControlTextButton',
'hitTest', 0
sleep 1
end
end
a
Once the GUI has the canned test data, we can push some buttons.
Three things to note: 1) Bromine can scroll controls into view so they
can be tapped; 2) since Bromine sees the view hierarchy as one big XML
tree, we specify controls using XPath; and 3) simulateSwipe is deprecated
—a new version of this slide’s code is posted on GitHub.
42. class JustPlayed
def stations
xml = @gui.dump
doc = REXML::Document.new xml
xpath = '//UITableViewCell[tag="%s"]' % StationTag
titles = REXML::XPath.match doc, xpath
titles.map {|e| e.elements['text'].text}
end
end
a
To get the result, we just serialize the entire GUI and grub through it
from the comfort of the desktop. This process is slow, but allows
Brominet to be built on a small set of primitives.
43. module Encumber
class GUI
def command(name, *params)
command = Tagz.tagz do
plist_(:version => 1.0) do
dict_ do
key_ 'command'
string_ name
params.each_cons(2) do |k, v|
key_ k
string_ v
end
end
end
end
Net::HTTP.post_quick
"http://#{@host}:#{@port}/", command
end
end
end g
All those library functions call into a common class whose responsibility
is posting HTTP requests. It uses the Tagz library to build XML requests
and Net::HTTP to send them. This part of the code should be reusable in
any Brominet project.
44. FAKING THE TIME
The canned-data approach is about to rear its head again, as we’re
going to fake out parts of the physical world.
45. Feature: Snaps
In order to find out what song is playing
As a radio listener without a mic or data
I want to remember songs for later lookup
Scenario: Snapping a song
Given a list of radio stations "KNRK"
And a current time of 23:45
Then the list of snaps should be empty
When I press KNRK
Then I should see the following snaps:
| station | time |
| KNRK | 11:45 PM |
s
The first thing I committed to the repository, even before creating a new
Xcode project, was an older version of this story.
See the line about the current time of 23:45?
46. Given /^a current time of (.*)$/ do
|time|
app.time = time
end
d
Without having control over the time, we’d have to resort to creating a
bookmark and then checking the time right after, with some sort of
fuzzy matching.
47. class JustPlayed
def time=(time)
@gui.command 'setTestData',
'testTime', time
end
end
a
The app has to support this testing hook internally and worry about
whether it’s supposed to use the real time or the fake one. This juggling
introduces complexity. But you’re seeing the worst case. The preloading
of radio stations you saw earlier met with a much happier fate: the
support code was useful for implementing save/restore.
49. Feature: Lookup
In order to find out what songs I heard earlier
As a radio listener with network access
I want to look up the songs I bookmarked
Scenario: Partial success
Given a list of radio stations "KNRK"
And a test server
And the following snaps:
| station | time |
| KNRK | 2:00 PM |
| KNRK | 12:00 PM |
When I look up my snaps
Then I should see the following snaps:
| title | subtitle |
| KNRK | 2:00 PM |
| Been Caught Stealing | Jane's Addiction |
s
You can draw ASCII-art tables right in your stories.
50. Given /^the following snaps:$/ do
|snaps_table|
snaps_table.hashes
#=> [{'station' => 'knrk', 'time' => '2:00 PM'} ...]
# do fancier things, like manipulating columns
app.snaps = snaps_from_table(snaps_table, :with_timestamp)
end
d
If a test step comes with its own table, Cucumber passes it into the
definition block as an object you can poke at. Most of the time, you’ll
just want to grab its “hashes” array, which gives you one hash per row.
But you can also do more complicated table processing, like renaming
columns.
51. TAGS
One more slice of Cucumber I found convenient for this project is the
notion of tagging tests as belonging to different categories.
52. Feature: Stations
...
@restart
Scenario: Remembering stations
Given a list of radio stations "KBOO,KINK"
And a test server
When I restart the app
Then I should see the stations "KBOO,KINK"
s
For instance... Apple’s Instruments tool doesn’t like it when your app
exits. So I tagged all the scenarios that required a restart.
54. RESULTS
For an investment of about 10% of the project’s time maintaining the
test infrastructure, using executable examples served to: 1) drive out the
design, 2) catch a couple of minor bugs, 3) help replicate other bugs
found manually, and 4) find leaks (mine and others’). Plus, now I know
what’s on the radio.
55. } /undees/justplayed
The app is available for free on the App Store. The source code is up on
the ‘Hub and in the ‘Bucket.
56. CONVERSATION
• Barnes and Noble booth
During lunch today
• Meet Authors from the Pragmatic Bookshelf
7 PM tonight, Ballroom A7
• undees@gmail.com
• http://twitter.com/undees
If you’d like to continue the conversation, catch me in the hall, or come
to one of the scheduled events.
57. SHOULDERS OF GIANTS
• Bromine • Pivotal Tracker
• cocoahttpserver • iBetaTest
• ASIHTTPRequest • api.yes.com
• hg-git
Special thanks to yes.com for making their radio playlist API available
under a Creative Commons license.
58. CREDITS
• Ruby icon (c) Iconshock
• Instrument photos (c) Tektronix
• Squirrel (cc) kthypryn on Flickr
• Hand (cc) myklroventine on Flickr
• Logos (tm) github and bitbucket
Writing the software and preparing the material for this talk has been a
blast. I can’t wait to see what the rest of OSCON has in store for us, and
am grateful for our time together this week. Cheers.
59.
60. BONUS SLIDES
Here are a few more tidbits that didn’t make it into the main
presentation.
61. UNIT TESTING
RSpec and iPhone—Dr. Nic Williams
http://drnicwilliams.com/2008/07/04/
unit-testing-iphone-apps-with-ruby-rbiphonetest/
I experimented a little with using Dr. Nic’s rbiphone library to unit-test
my Objective-C model classes from Ruby using the RSpec framework.
This technique wasn’t a perfect fit for the models in my app, which were
so tied to Apple APIs that there wasn’t much for the tests to do.
62. SCREEN CAPTURE
Google Toolbox for Mac
http://code.google.com/p/google-toolbox-for-mac/wiki/
iPhoneUnitTesting
Google has a suite of Mac and iPhone development tools. Their iPhone
unit test code is geared toward capturing screen images and comparing
them against a reference. Heavily graphical apps, or apps that don’t use
the standard UIKit controls, spring to mind for a technique like this.