<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Vinicius Horewicz</title>
 <link href="http://horewi.cz/atom.xml" rel="self"/>
 <link href="http://horewi.cz/"/>
 <updated>2011-12-17T17:48:55-08:00</updated>
 <id>http://horewi.cz/</id>
 <author>
   <name>Vinicius Horewicz</name>
   <email>vinicius@horewi.cz</email>
 </author>

 
 <entry>
   <title>My TODO list</title>
   <link href="http://horewi.cz/my-todo-list"/>
   <updated>2011-12-17T00:00:00-08:00</updated>
   <id>http://horewi.cz/my-todo-list</id>
   <content type="html">&lt;p&gt;A &lt;a href=&quot;http://about.me/victorhg&quot;&gt;friend&lt;/a&gt; &lt;a href=&quot;https://twitter.com/victorhg/status/142079139220946944&quot;&gt;tweeted&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I use pending specs instead of TODO lists... nice tip from @wicz... it gives me an interesting view of what is missing.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I told Victor to write pending specs in place of using TODO comments within his code. I'm glad he liked the idea. I've been using the pending specs technique for a while and I'd like to share my thoughts why you should do the same.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;you shouldn't add comments unless they are extremely necessary.&lt;/strong&gt; As good developers, we strive to write clean, concise and self-explanatory code. We always refactor our code to make it as clear as possible for others to understand and to avoid to use of unnecessary comments. Using TODO comments go against our principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TODO comments are easily forgotten and overlooked. And your tests are not!&lt;/strong&gt; How often do you &lt;code&gt;ack TODO&lt;/code&gt;? And how often you run your test suite? I bet you've answered &lt;em&gt;sometimes&lt;/em&gt; and &lt;em&gt;everytime&lt;/em&gt;. And how about your CI server? I'm not sure if it knows anything about TODO comments, but it can certainly cope with pending tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TODO comments are just wrong!&lt;/strong&gt; Specially if you're using them to convey something your code should be doing. What your code needs to do is its specification, and we all know the right place to put it.&lt;/p&gt;

&lt;p&gt;So, are you still using TODO comments? I'd love to hear your opinions on the comments below.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>First mutuo sketches</title>
   <link href="http://horewi.cz/first-mutuo-sketches"/>
   <updated>2011-05-12T20:25:08-07:00</updated>
   <id>http://horewi.cz/first-mutuo-sketches</id>
   <content type="html">&lt;p&gt;Here is the digital version of the very first sketch I've made of mutuo architecture.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.lucidchart.com/publicSegments/view/4dcbf144-143c-4c11-ab26-08950a56d291/image.png&quot; alt=&quot;mutuo prototype&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I know it's a raw draft, but doing this made me understand things clearly, so I guess it could ease things for you too. I'm not trying to follow any convention here, it's just a free-format sketch. Here we have the four core parts of mutuo: &lt;em&gt;agent&lt;/em&gt;, &lt;em&gt;tracker&lt;/em&gt;, &lt;em&gt;receiver&lt;/em&gt; and the &lt;em&gt;app&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;The agent&lt;/h2&gt;

&lt;p&gt;The agent is the service which will be running in the peers. He's responsible for doing the heavy duty of the platform, which is monitor the others peers. It will somehow get a list of peers from the tracker, do whatever it has to do and report the results to the receiver.&lt;/p&gt;

&lt;p&gt;I'm not being vague here on purpose, it's because there are lots of questions to be answered. For instance, I haven't defined yet how the agent will communicate with the tracker. Almost certainly it will run over HTTP, but I haven't defined if it will be long polling a REST API or use some kind of publish-subscribe mechanism, like &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot;&gt;pubsubhubbub&lt;/a&gt; or &lt;a href=&quot;http://faye.jcoglan.com/&quot;&gt;Faye&lt;/a&gt;. Probably I'll stick with the pubsub approach.&lt;/p&gt;

&lt;p&gt;What I know, is that it's going to be implemented using &lt;a href=&quot;http://nodejs.org/&quot;&gt;node.js&lt;/a&gt; with &lt;a href=&quot;http://jashkenas.github.com/coffee-script/&quot;&gt;CoffeeScript&lt;/a&gt;. Since I don't want to overwhelm the peers, I believe node.js will give the performance and small footprint I'm looking for.&lt;/p&gt;

&lt;h2&gt;The tracker&lt;/h2&gt;

&lt;p&gt;The tracker is supposed to be very similar to a BitTorrent tracker. It will keep track of the alive peers and serve them as a list.&lt;/p&gt;

&lt;p&gt;It will also need to know if a agent who's trying to subscribe is a valid one. I'm thinking in a token-based authentication. Users will register agents in the app, which in turn will generate the tokens for them. That's why the tracker will need access to the app database.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;status&lt;/em&gt; database is where the tracker will store the peers' status. It could be a simple container data structure, or I could use something more interesting like &lt;a href=&quot;http://memcached.org/&quot;&gt;memcached&lt;/a&gt; or &lt;a href=&quot;http://redis.io/&quot;&gt;redis&lt;/a&gt; or &lt;a href=&quot;http://fallabs.com/kyototycoon/&quot;&gt;Kyoto Tycoon&lt;/a&gt;. It will be much easier to implement multiple trackers in the future using some of these. Now, which one? Probably I'll create an abstraction layer and delegate to the appropriate drivers. Thus I could play with all of them.&lt;/p&gt;

&lt;p&gt;I want both tracker and receiver to be written in Ruby, and since both will be struggling with &lt;a href=&quot;http://www.kegel.com/c10k.html&quot;&gt;the C10k problem&lt;/a&gt;, I think it'll be a great opportunity to get  my hands on &lt;a href=&quot;http://postrank-labs.github.com/goliath/&quot;&gt;Goliath&lt;/a&gt;, &lt;a href=&quot;https://github.com/eventmachine/eventmachine&quot;&gt;EventMachine&lt;/a&gt; or &lt;a href=&quot;http://coolio.github.com/&quot;&gt;cool.io&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;The receiver&lt;/h2&gt;

&lt;p&gt;As it's name suggests, it basically receives all the data retrieved by the agents. It will also need to authenticate the agents, so it needs access to the app database (though it's not on the graph, I've just realized it... my bad!)&lt;/p&gt;

&lt;p&gt;I'm still thinking on how I'll store the massive amount of data. Could be redis, or for some type of data I could use &lt;a href=&quot;http://en.wikipedia.org/wiki/RRDtool&quot;&gt;RRD&lt;/a&gt; or &lt;a href=&quot;http://graphite.wikidot.com/&quot;&gt;Graphite&lt;/a&gt;. That would be nice when generating the reports.&lt;/p&gt;

&lt;p&gt;Maybe I just answered my own question: It depends! It will depend on the type of the data. Is it time-based? Is it a sort of report, like page load? My brain's hurting now, so let's decide it later.&lt;/p&gt;

&lt;h2&gt;The app&lt;/h2&gt;

&lt;p&gt;The app will be the user interface for all the platform. I'll probably use Rails for this. Haven't thought much about it, but I do know it will have a simple, clean and very user-friendly interface. And maybe some realtime statistics using Websockets? &lt;a href=&quot;http://pusher.com/&quot;&gt;Pusher&lt;/a&gt; looks interesting.&lt;/p&gt;

&lt;p&gt;That's pretty much it, for a start at least. Was it worth reading all this? What do you think? Am I missing something? Please be my guest to post your opinions on the comments.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>mutuo: peer-to-peer monitoring</title>
   <link href="http://horewi.cz/mutuo-peer-to-peer-monitoring"/>
   <updated>2011-05-12T00:00:00-07:00</updated>
   <id>http://horewi.cz/mutuo-peer-to-peer-monitoring</id>
   <content type="html">&lt;p&gt;Meet &lt;a href=&quot;https://github.com/wicz/mutuo&quot;&gt;mutuo&lt;/a&gt;, my brand new pet project! mutuo is a resources monitoring system based on a peer-to-peer architecture.&lt;/p&gt;

&lt;p&gt;The first idea is to create something like &lt;a href=&quot;http://www.pingdom.com&quot;&gt;pingdom&lt;/a&gt;, but in a fully distributed architecture similar to a BitTorrent network. We'll have peers (or agents) which subscribes to a tracker and get a list of other subscribed peers to ping. Ultimately the results are sent to another server and the reports accessible via an web app.&lt;/p&gt;

&lt;p&gt;That done, we can extend mutuo to support other monitoring services with different protocols like &lt;a href=&quot;http://www.watchmouse.com/en/website_monitoring_features.php&quot;&gt;WatchMouse&lt;/a&gt;, or full page load evaluations like &lt;a href=&quot;http://portal.monitis.com/index.php/products&quot;&gt;Monitis&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/speed/page-speed&quot;&gt;Page Speed&lt;/a&gt;, and even stress tests like &lt;a href=&quot;http://loadimpact.com&quot;&gt;Load Impact&lt;/a&gt;. I know it may look like I want to conquer the world, but that's not the point. I just want to raise the bar here and put on the table all my options. Like I said, it's a pet project, for fun and no profit =)&lt;/p&gt;

&lt;p&gt;One thing I kept asking myself was &quot;What I want with that?&quot;. And finally I was able to write my real intentions and motivations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learn&lt;/strong&gt;. I want to learn new techniques, methodologies and technologies. I want to try Node.js, CoffeeScript, Redis and other things, and understand their better use. I want to learn more about event-based programming, concurrency, statistics and how to build and maintain an acceptable heterogeneous platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Practice&lt;/strong&gt;. I want to practice, and I mean, A LOT! I want to try harder and harder. I consider myself an average programmer. I'm not dumb, but I'm not a genius either. I study a lot, but reading with no practicing will lead me to nowhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Push&lt;/strong&gt;. I want to push myself to a new challenge. I want to face new problems and push myself to come up with ideas and solutions. I want to leave this comfort zone I am in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exposure&lt;/strong&gt;. I want to expose my skills, my code and way of thinking. I want people to see what I am capable of and what I need to improve. And I really hope to get some feedback. Maybe I'll also have the chance to pair with some smart people like &lt;a href=&quot;http://www.railway.at/2011/04/23/code-with-me/&quot;&gt;Clemens Kofler&lt;/a&gt; and &lt;a href=&quot;http://patmaddox.com/blog/pair-with-me&quot;&gt;Pat Maddox&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Give back&lt;/strong&gt;. And last, but not least. I want to give back to the community. Be it Ruby, Rails or any other community. I want to give back my support. I want people to learn something from me, I want to help others like I was helped. In order to do that, I'll open-source everything produced, I'll do my best to keep the service running on my own servers and I won't charge a penny!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I guess that's it. I'll start pushing some code to the repo soon and continue to write my thoughts here, so stay tuned.&lt;/p&gt;

&lt;p&gt;If you want to help me, feel free to email, fork, send you pull requests, discuss on the comments, whatever it takes to us to communicate. Any feedback will be really appreciated.&lt;/p&gt;

&lt;p&gt;Wish me luck!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hello Alfred App, how can I completely disable Spotlight?</title>
   <link href="http://horewi.cz/hello-alfred-app-how-can-i-completely-disable-spotlight"/>
   <updated>2011-05-04T00:00:00-07:00</updated>
   <id>http://horewi.cz/hello-alfred-app-how-can-i-completely-disable-spotlight</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;UPDATE 2011-05-10:&lt;/strong&gt; STOP RIGHT NOW! After a few days I wrote this, I realized that Alfred &lt;strong&gt;uses&lt;/strong&gt; the metadata services, which means if you disable it, Alfred will stop working. Why I couldn't find anything about that in their docs? I'm still using it, though I'm not sure if I'll keep it.&lt;/p&gt;

&lt;p&gt;So, finally I'm giving &lt;a href=&quot;http://www.alfredapp.com&quot;&gt;Alfred App&lt;/a&gt; a try. It reminds me a lot the (discontinued?) &lt;a href=&quot;http://www.humanized.com/enso/&quot;&gt;Enso&lt;/a&gt; from Humanized.&lt;/p&gt;

&lt;p&gt;Since I'll be using Alfred in favor of Spotlight, I want to disable the latter. Googling a bit gives us a lot of ways to do it, but all looks a bit intrusive and destructive to me. I don't want to delete Spotlight, I just want to disable it!&lt;/p&gt;

&lt;p&gt;Spotlight consists of a set backend and frontend tools. Metadata server (mds), Metadata worker (mdworker), etc. do the hard work of indexing the volumes and monitoring file changes. The frontend is basically the small loupe that appears in the menu bar (that's enough, we don't need all the details.)&lt;/p&gt;

&lt;p&gt;The first thing is to disable all backend. You can stop the mds from indexing your volumes:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo mdutil -a -v -i off
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;OK, but it won't stop Spotlight from initiating after a system restart. According to other solutions, you could delete files from &lt;code&gt;/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support&lt;/code&gt;, but since I don't want to destroy anything, I chose to reset the permissions:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo chmod 000 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/*
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Great! &lt;code&gt;ps aux | grep md&lt;/code&gt; shows no metadata processes running. &lt;code&gt;dmesg&lt;/code&gt; shows no error. But looking at Console.app (/var/log/system.log) I see that launchd is trying to start &lt;code&gt;mds&lt;/code&gt; every 10 seconds!&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;May 3 11:41:11 wicz com.apple.launchd[1] (com.apple.metadata.mds[879]): posix_spawn(&amp;quot;/System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds&amp;quot;, ...): Permission denied&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;May 3 11:41:11 wicz com.apple.launchd[1] (com.apple.metadata.mds[879]): Exited with exit code: 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;May 3 11:41:11 wicz com.apple.launchd[1] (com.apple.metadata.mds): Throttling respawn: Will start in 10 seconds &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Well, I don't wanna lose those CPU cycles. So &lt;code&gt;chmod&lt;/code&gt; isn't a acceptable solution and neither is deleting those files. Probably the error would be &lt;code&gt;No such file or directory&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The acceptable solution is to disable &lt;code&gt;mds&lt;/code&gt; in &lt;code&gt;launchd&lt;/code&gt;. So, RTFM! &lt;code&gt;manpage launchctl&lt;/code&gt;* has the answer we're looking for:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now to the frontend. I didn't find a way to disable this nicely. It seems to be somehow hard coded in the SystemUIServer.app. So here we have to use the &lt;code&gt;chmod&lt;/code&gt; approach. At least it is just a one time failure.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;5/3/11 11:31:46 AM SystemUIServer[256] Error loading /System/Library/CoreServices/Search.bundle/Contents/MacOS/Search: dlopen(/System/Library/CoreServices/Search.bundle/Contents/MacOS/Search, 265): no suitable image found. Did find: /System/Library/CoreServices/Search.bundle/Contents/MacOS/Search: open() failed with errno=13&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;OK, errno=13 is an EACCES Permission denied. No loupe appears on menu bar. But I wonder if it will crash future system updates. So I ended up just renaming the damn thing.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /System/Library/CoreServices/Search.bundle/Contents/MacOS
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sudo mv Search _Search
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It seems everything is fine till now. If something stop working I'll update this post. And if you know something I'm missing, please let me know in the comments.&lt;/p&gt;

&lt;p&gt;*Just a few notes. Reading the launchctl manpage it says:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;-w Overrides the Disabled key and sets it to true. In previous versions, this option would modify the configuration file. Now the state of the Disabled key is stored elsewhere on-disk.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;WTF!? &quot;elsewhere on-disk&quot;? FWIW, the &quot;elsewhere&quot; is &lt;code&gt;/private/var/db/launchd.db/com.apple.launchd.peruser.&amp;lt;userid&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And launchctl looks at many different places for .plist files. So if you're getting errors from apps that you've already uninstalled but are still trying to start, you might want take a look into:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;~/Library/LaunchAgents -- Per-user agents provided by the user.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;/Library/LaunchAgents -- Per-user agents provided by the administrator.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;/Library/LaunchDaemons -- System wide daemons provided by the administrator.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;/System/Library/LaunchAgents -- Mac OS X Per-user &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;/System/Library/LaunchDaemons -- Mac OS X System wide daemons.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 </entry>
 
 <entry>
   <title>HAI SPARROW, CAN I HAS FIXED WIDTH FONTZ? KTHXBYE</title>
   <link href="http://horewi.cz/hai-sparrow-can-i-has-fixed-width-fontz-kthxbye"/>
   <updated>2011-05-04T00:00:00-07:00</updated>
   <id>http://horewi.cz/hai-sparrow-can-i-has-fixed-width-fontz-kthxbye</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;UPDATE 2011-12-15:&lt;/strong&gt; I'm no longer using the trial version, like said in the comments months ago. I'm using this with Sparrow Version 1.5 (1043) and it's working flawless. No code signatures problems either.&lt;/p&gt;

&lt;p&gt;Gotta say, I just love the &lt;a href=&quot;http://www.sparrowmailapp.com/&quot;&gt;Sparrow Mail App&lt;/a&gt;! It's interface is simple and clean. It just does everything you need, and nothing you don't.&lt;/p&gt;

&lt;p&gt;Only one thing I can complain: Why in hell I can't set a fixed width font for plain text messages? I don't like HTML emails and I never use that fancy editor. I like plain old fixed fonts! Just like my terminal.&lt;/p&gt;

&lt;p&gt;If you're like me, dark days are over! All you need is tweak some CSS and voila! Inside &lt;code&gt;/Applications/Sparrow.app/Contents/Resources/&lt;/code&gt;&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;css&quot;&gt;&lt;span class=&quot;special&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;6&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;message-editing&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.css&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Monospace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;conversation&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.css&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.-sparrow-messageBody&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Monospace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.-sparrow-quickReplyTextContents&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Monospace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;



</content>
 </entry>
 
 <entry>
   <title>Testing subdomains and redirects with Cucumber</title>
   <link href="http://horewi.cz/testing-subdomains-and-redirects-with-cucumber"/>
   <updated>2009-12-09T00:00:00-08:00</updated>
   <id>http://horewi.cz/testing-subdomains-and-redirects-with-cucumber</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;UPDATE 2011-04-13:&lt;/strong&gt; If you're on Mac OS X, forget all the /etc/hosts and PAC thing and go for &lt;a href=&quot;http://pow.cx/&quot;&gt;Pow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The other day I was writing some Cucumber features for a Rails app that relies on subdomains for creating per-user contexts. It seems that Webrat can't handle subdomains and redirects the way I expected.&lt;/p&gt;

&lt;h2&gt;A Little Background&lt;/h2&gt;

&lt;p&gt;I hate when I have to access 127.0.0.1 or localhost:3000. Typing all these numbers, dots and colon doesn't feel comfortable at all. I like domain names, and since I am developing a subdomain-aware app, I want to be able to access using names. That said, I configured my Firefox with a PAC file that routes *.local to my server running at 127.0.0.1:3000 (oh man, if you're still using /etc/hosts you're so 2000-and-late! =p).&lt;/p&gt;

&lt;p&gt;Here's how it looks like. You can grab more details here.&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;special&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;6&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FindProxyForURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;shExpMatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*.local&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;PROXY 127.0.0.1:3000&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;DIRECT&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Now I am able to access johndoe.app.local, foobar.app.local, etc. No numbers, no colon, just NAMES! =)&lt;/p&gt;

&lt;p&gt;My ApplicationController implements a simple before_filter that checks for a valid account, otherwise redirects to a fallback page. Something like this:&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;special&quot;&gt; 1&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 2&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 3&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 4&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 5&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 6&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 7&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 8&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt; 9&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;12&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;before_filter&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:account_required&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;current_account&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@current_account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_by_subdomain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subdomains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;account_required&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_account&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;flash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:account_not_found&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;redirect_to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fallback_url&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;You can have more on subdomains as accounts here, here and here.&lt;/p&gt;

&lt;h2&gt;The Scenario&lt;/h2&gt;

&lt;p&gt;The feature was a simple sign in.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;gherkin&quot;&gt;&lt;span class=&quot;k&quot;&gt;Given &lt;/span&gt;the foobar account
&lt;span class=&quot;k&quot;&gt;When &lt;/span&gt;I go to foobar&amp;#39;s sign in page 
&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;I fill in &lt;span class=&quot;s&quot;&gt;&amp;quot;user_session[email]&amp;quot;&lt;/span&gt; with &lt;span class=&quot;s&quot;&gt;&amp;quot;foobar@test.com&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;I fill in &lt;span class=&quot;s&quot;&gt;&amp;quot;user_session[password]&amp;quot;&lt;/span&gt; with &lt;span class=&quot;s&quot;&gt;&amp;quot;1234&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;I press &lt;span class=&quot;s&quot;&gt;&amp;quot;Sign in&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Then &lt;/span&gt;I should be on dashboard
&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;I should see &lt;span class=&quot;s&quot;&gt;&amp;quot;Welcome, foobar&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;The Caveats&lt;/h2&gt;

&lt;p&gt;By default, Webrat uses www.example.com as host for testing. Since it was trying to sign in to a account that doesn't exist (the Given creates foobar), it was being redirect to the fallback url, so it couldn't find the form fields. Knowing that Webrat's RailsAdapter uses ActionController::Integration::Session, we can easily solve this by overwriting the host name to use in the next request. Our Given should look like this:&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;special&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;no&quot;&gt;Given&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /^the foobar account$/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Foobar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;host!&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;foobar.app.local&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Now being able to fill in the form, after submitting it, I still wasn't sent to the expected page. I was willing to see the dashboard, but it was rendering /session, which means I wasn't authenticating at all, even passing valid credentials... WTF!? Then dumping the ActionController::Response object, I verified that it was actually redirecting (@status =&gt; &quot;302 Found&quot;), so I decided to investigate Webrat.&lt;/p&gt;

&lt;p&gt;Webrat's behavior is to follow any redirects, except for external ones. And subdomains aren't considered as externals. Digging a little deeper, people have reported similar problems and patches (although I've tried none) here, here, here and here. Since the problem seems that Webrat shows some really deep love to example.com, I came up with a ugly-and-fast-but-it-works solution:&lt;/p&gt;

&lt;p&gt;Set a domain in my environment.rb:&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;special&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;special&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;no&quot;&gt;APP_DOMAIN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;app.&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RAILS_ENV&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;production&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;com&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cucumber&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;example.com&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;local&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;And changed the above Given step to  &lt;code&gt;host! &quot;foobar.#{APP_DOMAIN}&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bar green, code clean, life moves on.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>User-friendly location-aware web apps</title>
   <link href="http://horewi.cz/user-friendly-location-aware-web-apps"/>
   <updated>2009-12-07T00:00:00-08:00</updated>
   <id>http://horewi.cz/user-friendly-location-aware-web-apps</id>
   <content type="html">&lt;p&gt;Who have never ever filled a form like this please stand up.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3005/3023466477_00845529c9_o.jpg&quot;&gt;&lt;/p&gt;

&lt;p&gt;Anyone? Anyone?&lt;/p&gt;

&lt;p&gt;Well, you'll have to agree with me that filling forms like this is a PITA! But I understand that may be necessary in certain cases. Maybe in apps that people really need this granularity, this is an easy way to get each field of an address separately.&lt;/p&gt;

&lt;p&gt;But if it's not your case and like me you can sacrifice the formalism in order to user experience, I present you &lt;a href=&quot;http://code.google.com/p/geo-autocomplete/&quot;&gt;geo-autocomplete&lt;/a&gt;. It's a nice jQuery plugin to autocomplete location using Google Maps v3 API and Google Static Maps v2 API.&lt;/p&gt;

&lt;p&gt;Now you are able to change that gigantic form to a simple textarea, and still have a nicely formatted address. And since the plugin queries the Google Maps v3 API Geocoder, you also get latitude and longitude values. It's fast and smooth, definitely worthwhile to give it a try.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Escrevendo boas User Stories</title>
   <link href="http://horewi.cz/escrevendo-boas-user-stories"/>
   <updated>2007-11-19T00:00:00-08:00</updated>
   <id>http://horewi.cz/escrevendo-boas-user-stories</id>
   <content type="html">&lt;p&gt;Como bem sabemos, um dos &lt;a style=&quot;opacity: 1;&quot; href=&quot;http://agilemanifesto.org/principles.html&quot;&gt;princ&amp;iacute;pios&lt;/a&gt; dos processos &amp;Aacute;geis &amp;eacute; satisfazer o cliente, agregando valor  ao produto final. De certa forma, para que essa tarefa possa ser realizada com sucesso, &amp;eacute; preciso saber exatamente as necessidades desse cliente.&lt;/p&gt;
&lt;p&gt;Felizmente com algumas &lt;a href=&quot;http://www.extremeprogramming.org/rules/userstories.html&quot;&gt;est&amp;oacute;rias&lt;/a&gt; e feedbacks j&amp;aacute; &amp;eacute; poss&amp;iacute;vel ter uma boa id&amp;eacute;ia de onde devemos chegar. Mas &amp;eacute; importante ressaltar que a &amp;ldquo;qualidade&amp;rdquo; das est&amp;oacute;rias influencia diretamente em todo o processo.&lt;/p&gt;
&lt;p&gt;As est&amp;oacute;rias apresentam tr&amp;ecirc;s aspectos cr&amp;iacute;ticos, os quais devem ser obrigatoriamente lembrados no momento de sua cria&amp;ccedil;&amp;atilde;o. S&amp;atilde;o eles: &lt;strong&gt;C&lt;/strong&gt;ards, &lt;strong&gt;C&lt;/strong&gt;onversation, &lt;strong&gt;C&lt;/strong&gt;onfirmation. Ou &lt;strong&gt;3C&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;C&lt;/strong&gt;ards &amp;mdash; Est&amp;oacute;rias s&amp;atilde;o escritas em &lt;strong&gt;cart&amp;otilde;es&lt;/strong&gt; ou post-its. Na verdade o que importa aqui &amp;eacute; o tamanho! A sugest&amp;atilde;o dos cart&amp;otilde;es e post-its &amp;eacute; pelo fato de serem pequenos. E cart&amp;otilde;es pequenos naturalmente for&amp;ccedil;am est&amp;oacute;rias pequenas, de duas a tr&amp;ecirc;s linhas no m&amp;aacute;ximo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C&lt;/strong&gt;onversation &amp;mdash; A est&amp;oacute;ria escrita no cart&amp;atilde;o serve como um lembrete, uma maneira de identificar uma funcionalidade que foi &lt;strong&gt;conversada&lt;/strong&gt; e discutida entre os clientes e desenvolvedores.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C&lt;/strong&gt;onfirmation &amp;mdash; Depois das funcionalidades terem sido discutidas e escritas nos cart&amp;otilde;es, o cliente define (impl&amp;iacute;cita ou explicitamente) uma maneira de validar esse pedido. Geralmente essa &lt;strong&gt;confirma&amp;ccedil;&amp;atilde;o&lt;/strong&gt; &amp;eacute; feita com testes de aceita&amp;ccedil;&amp;atilde;o.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Para criar boas est&amp;oacute;rias, ainda devemos focar em seis atributos: &lt;strong&gt;INVEST&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I&lt;/strong&gt;ndependent &amp;mdash; Est&amp;oacute;rias devem ser independentes uma das outras. Depend&amp;ecirc;ncias entre est&amp;oacute;rias geram problemas de planejamento e prioriza&amp;ccedil;&amp;atilde;o, sem falar que dificultam bastante nas estimativas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;N&lt;/strong&gt;egotiable &amp;mdash; Est&amp;oacute;rias n&amp;atilde;o s&amp;atilde;o contratos. Como dito anteriomente, est&amp;oacute;rias s&amp;atilde;o lembretes para funcionalidades discutidas (negociadas) entre o cliente e os desenvolvedores.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;V&lt;/strong&gt;aluable &amp;mdash; Na mesma linha dos processos &amp;Aacute;geis, como dito no in&amp;iacute;cio deste post. Est&amp;oacute;rias devem agregar valor para o cliente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;E&lt;/strong&gt;stimatable &amp;mdash; Os desenvolvedores devem ser capazes de estimar o tamanhos das est&amp;oacute;rias. Geralmente est&amp;oacute;rias incompletas ou muito grandes (complexas) s&amp;atilde;o dif&amp;iacute;ceis de serem estimadas. Portanto invista em discuss&amp;otilde;es e quebre em est&amp;oacute;rias menores quando necess&amp;aacute;rio.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;S&lt;/strong&gt;mall &amp;mdash; &amp;ldquo;Tamanho &amp;eacute; documento&amp;rdquo;. Essa regra &amp;eacute; valida para a cria&amp;ccedil;&amp;atilde;o de boas est&amp;oacute;rias. Como dito anteriormente, est&amp;oacute;rias grandes dificultam as estimativas. Bem como est&amp;oacute;rias muito pequenas. Quebre ou agrupe dependendo do caso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;T&lt;/strong&gt;estable &amp;mdash;  Est&amp;oacute;rias devem ser poss&amp;iacute;veis de serem testadas. Um teste que &amp;eacute; executado com sucesso, prova que a est&amp;oacute;ria foi desenvolvida com sucesso, atingindo as necessidades do cliente. Est&amp;oacute;rias que n&amp;atilde;o podem ser testadas geralmente especificam requisitos n&amp;atilde;o-funcionais do software, e n&amp;atilde;o uma funcionalidade diretamente.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Al&amp;eacute;m do 3C e INVEST, vejamos mais alguns pontos. Foque as est&amp;oacute;rias no &amp;ldquo;O que&amp;rdquo; e n&amp;atilde;o no &amp;ldquo;Porque&amp;rdquo;. Est&amp;oacute;rias &lt;strong&gt;n&amp;atilde;o&lt;/strong&gt; devem apresentar termos t&amp;eacute;cnicos e nem os m&amp;iacute;nimos detalhes das funcionalidades. Lembre-se, elas s&amp;atilde;o apenas lembretes do que foi discutido anteriomente.&lt;/p&gt;
&lt;p&gt;Quando poss&amp;iacute;vel aplique o &amp;ldquo;Quem&amp;rdquo;, &amp;ldquo;O que&amp;rdquo; e &amp;ldquo;Como&amp;rdquo;. Por exemplo: &amp;ldquo;O visitante pode se cadastrar no portal pelo formul&amp;aacute;rio&amp;rdquo;, &amp;ldquo;O visitante confirma seu cadastro por email&amp;rdquo;, &amp;ldquo;O usu&amp;aacute;rio &amp;eacute; capaz de salvar seus favoritos&amp;rdquo;. Mas cuidado com o detalhismo!&lt;/p&gt;
&lt;p&gt;Use e abuse de &lt;a href=&quot;http://www.improveit.com.br/xp/praticas/metafora&quot;&gt;met&amp;aacute;foras&lt;/a&gt;. Voc&amp;ecirc; vai perceber como fica f&amp;aacute;cil de explicar (ou entender) suas id&amp;eacute;ias quando voc&amp;ecirc; consegue comparar com algo concreto, do dia-a-dia das pessoas. Sem falar que assim voc&amp;ecirc; consegue definir um vocabul&amp;aacute;rio comum com o cliente.&lt;/p&gt;
&lt;p&gt;Incentive o cliente a escrever as est&amp;oacute;rias. Assim voc&amp;ecirc; acaba for&amp;ccedil;ando-o a explicar com clareza as suas necessidades e muitas vezes ajuda tamb&amp;eacute;m a esclarecer poss&amp;iacute;veis d&amp;uacute;vidas.&lt;/p&gt;
&lt;p&gt;Para finalizar, abaixo um trecho retirado de [1], que explica quase tudo em um &amp;uacute;nico par&amp;aacute;grafo:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The story is the unit of functionality in an XP project. We demonstate progress by delivering tested, integrated code that implements a story. A story should be understandable to customers and developers, testable, valuable to the customer, and small enough so that the programmers can build half a dozen in an iteration&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Refer&amp;ecirc;ncias/Leitura recomendada:&lt;/p&gt;
&lt;p&gt;[1]  &lt;a href=&quot;http://www.amazon.com/Planning-Extreme-Programming-Kent-Beck/dp/0201710919&quot;&gt;Planning Extreme Programming.&lt;/a&gt; Kent Beck, Martin Fowler&lt;br /&gt; [2]  &lt;a href=&quot;http://www.xprogramming.com/xpmag/expCardConversationConfirmation.htm&quot;&gt;Essential XP: Card, Conversation, Confirmation.&lt;/a&gt; Ron Jeffries&lt;br /&gt; [3]  &lt;a href=&quot;http://www.submarino.com.br/imports_productdetails.asp?Query=ProductPage&amp;amp;ProdTypeId=9&amp;amp;ProdId=744298&amp;amp;franq=255004&quot;&gt;User Stories Applied: For Agile Software Development&lt;/a&gt;. Mike Cohn&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Dicas valiosas para sprints</title>
   <link href="http://horewi.cz/dicas-valiosas-para-sprints"/>
   <updated>2007-10-23T00:00:00-07:00</updated>
   <id>http://horewi.cz/dicas-valiosas-para-sprints</id>
   <content type="html">&lt;p&gt;Ol&amp;aacute;. Bem, &amp;eacute; como dizem por ai: &amp;ldquo;Life got real!&amp;rdquo;. Mas, enfim, estou aqui de volta.&lt;/p&gt;
&lt;p&gt;Ainda tratando de sprints. Seguindo na mesma linha do &lt;a title=&quot;Tamanho ideal de sprint/itera&amp;ccedil;&amp;atilde;o (Scrum/XP).&quot; href=&quot;http://horewicz.net/tamanho-ideal-de-sprintiteracao-scrumxp/&quot;&gt;post anterior&lt;/a&gt;. Acho que ficou claro que n&amp;atilde;o &amp;eacute; sensato abra&amp;ccedil;ar cegamente o que &amp;eacute; sugerido pela literatura, e sim saber reconhecer a ess&amp;ecirc;ncia do que &amp;eacute; proposto e conseguir adaptar e aplicar &amp;agrave; sua realidade. E al&amp;eacute;m do mais, saber aplicar tais conceitos a cada caso &amp;eacute; o tipo de tarefa que s&amp;oacute; se consegue realizar com a pr&amp;aacute;tica do dia-a-dia. E foi justamente com a pr&amp;aacute;tica do dia-a-dia que eu percebi alguns detalhes nos meus projetos. Seguinte:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fixe os dias da semana para marcar suas reuni&amp;otilde;es de planejamento e retrospectiva (sprint planning e review).&lt;/strong&gt; Por exemplo, todos os plannings acontecem na segunda-feira e todos os reviews na sexta-feira. Dessa forma voc&amp;ecirc; acaba criando um v&amp;iacute;nculo e fica mais f&amp;aacute;cil de todos se organizarem e dificilmente algu&amp;eacute;m vai esquecer da reuni&amp;atilde;o;&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Certifique-se que os dias dos sprints planning e reviews est&amp;atilde;o &amp;ldquo;funcionando&amp;rdquo; pra voc&amp;ecirc;.&lt;/strong&gt; O que eu quero dizer com funcionando, &amp;eacute; se est&amp;atilde;o sendo reuni&amp;otilde;es produtivas. Nos meus primeiros projetos eu reservava a segunda-feira para o planejamento e a sexta-feira (da outra semana) para as retrospectivas. Tiro no p&amp;eacute;! Ningu&amp;eacute;m, nem a equipe, nem o Product Owner estavam motivados para come&amp;ccedil;ar a semana com uma reuni&amp;atilde;o. Estas sempre come&amp;ccedil;avam atrasadas e era n&amp;iacute;tido que o pessoal ainda estava &amp;ldquo;regulando a marcha lenta&amp;rdquo;. Muito menos encarar uma retrospectiva de 4 horas em plena sexta-feira! Bastou trocar os dias e a coisa come&amp;ccedil;ou a funcionar;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lan&amp;ccedil;ar novas vers&amp;otilde;es do produto na sexta-feira pode n&amp;atilde;o ser uma boa id&amp;eacute;ia.&lt;/strong&gt; Ningu&amp;eacute;m quer voltar para casa, muito menos correr o risco de perder o final de semana com aquela preocupa&amp;ccedil;&amp;atilde;o de que algo pode dar errado. Uma coisa que funcionou comigo foi definir um deadline na quinta-feira. E deixar a sexta-feira apenas para algumas tarefas administrativas e reviews;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Crie tags no seu sistema de controle vers&amp;atilde;o para cada sprint.&lt;/strong&gt; Isso se voc&amp;ecirc; estiver utilizando controle de vers&amp;atilde;o, pois se n&amp;atilde;o estiver, voc&amp;ecirc; definitivamente deveria!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evite entregar tudo o que foi produzido apenas ao final da itera&amp;ccedil;&amp;atilde;o. A medida que as tarefas forem sendo finalizadas, disponibilize para o cliente.&lt;/strong&gt; Agilidade est&amp;aacute; diretamente relacionada a feedback. Se voc&amp;ecirc; deixar para entregar tudo que foi feito ao final do sprint, voc&amp;ecirc; s&amp;oacute; tera o feedback do cliente no pr&amp;oacute;ximo sprint, o que pode acabar atrasando as coisas, haja vista j&amp;aacute; existem tarefas definidas para esse (pr&amp;oacute;ximo) sprint. Esse assunto tamb&amp;eacute;m foi abordado neste &lt;a title=&quot;Incrementos e Itera&amp;ccedil;&amp;otilde;es&quot; href=&quot;http://www.phidelis.com.br/blogs/alissonvale/2007/07/16/IncrementosEIteraccedilotildees.aspx&quot;&gt;excelente artigo&lt;/a&gt; do &lt;a title=&quot;Alisson Vale&quot; href=&quot;http://www.phidelis.com.br/blogs/alissonvale/&quot;&gt;Alisson Vale&lt;/a&gt;, inclusive batizado com um nome bastente adequado: &amp;ldquo;S&amp;iacute;ndrome da Itera&amp;ccedil;&amp;atilde;o Inacabada&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bem, por hora &amp;eacute; isso. Como cada empresa ou projeto, cada situa&amp;ccedil;&amp;atilde;o tem suas peculiaridades, eu gostaria que voc&amp;ecirc;s compartilhassem suas experi&amp;ecirc;ncias com rela&amp;ccedil;&amp;atilde;o a esse assunto. Os coment&amp;aacute;rio est&amp;atilde;o abertos. Caso voc&amp;ecirc; n&amp;atilde;o tenha passado por isso ainda, espero que esses t&amp;oacute;picos possam te poupar algum tempo.&lt;/p&gt;
&lt;p&gt;Sem mais.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tamanho ideal de sprint/iteração (Scrum/XP)</title>
   <link href="http://horewi.cz/tamanho-ideal-de-sprint"/>
   <updated>2007-10-10T00:00:00-07:00</updated>
   <id>http://horewi.cz/tamanho-ideal-de-sprint</id>
   <content type="html">&lt;p&gt;Antes que comecem as cr&amp;iacute;ticas, quero deixar claro que o t&amp;iacute;tulo escolhido foi proposital. N&amp;atilde;o por provoca&amp;ccedil;&amp;atilde;o, pelo contr&amp;aacute;rio, mas para tentar abrir os olhos de quem ainda acredita que seguir &amp;agrave; risca a bibliografia &amp;eacute; sempre a melhor solu&amp;ccedil;&amp;atilde;o. E acaba ferindo (mesmo que cegamente) um dos princ&amp;iacute;pios mais importantes da Agilidade: &lt;strong&gt;Adapta&amp;ccedil;&amp;atilde;o&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;N&amp;atilde;o me recordo o n&amp;uacute;mero, mas posso afirmar que n&amp;atilde;o foram poucas as vezes que ouvi ou li algu&amp;eacute;m questionando sobre o tamanho dos sprints ou itera&amp;ccedil;&amp;otilde;es. Se eram obrigados a trabalhar com 30 dias, ou se optando por um valor diferente estariam certos ou errados.&lt;/p&gt;
&lt;p&gt;Para quem esperava uma solu&amp;ccedil;&amp;atilde;o simples e objetiva, sinto muito. A verdade &amp;eacute; que n&amp;atilde;o existe bala de prata, nem certo ou errado. N&amp;atilde;o existe um tamanho ideal que se aplique a todas as ocasi&amp;otilde;es. Cada caso &amp;eacute; um caso. Mesmo em uma equipe que n&amp;atilde;o sofre altera&amp;ccedil;&amp;otilde;es de pessoal, um tamanho adequado para um projeto, pode n&amp;atilde;o ter a mesma efici&amp;ecirc;ncia em outro.&lt;/p&gt;
&lt;p&gt;O Scrum sugere sprints com 30 dias (um m&amp;ecirc;s) de dura&amp;ccedil;&amp;atilde;o (&lt;em&gt;&amp;ldquo;Do I need to stick to a month time frame?&amp;rdquo;&lt;/em&gt; em &lt;a title=&quot;Scrum FAQ Podcast Transcript&quot; href=&quot;http://blogs.conchango.com/howardvanrooijen/archive/2006/01/05/2553.aspx&quot; target=&quot;_blank&quot;&gt;Scrum FAQ&lt;/a&gt;, ou na &lt;a title=&quot;Scrum FAQ em portugu&amp;ecirc;s&quot; href=&quot;http://dojofloripa.wordpress.com/2007/09/28/scrum-faq-em-portugues/&quot; target=&quot;_blank&quot;&gt;vers&amp;atilde;o traduzida&lt;/a&gt;).  O XP sugere &lt;a title=&quot;Ciclo Semanal&quot; href=&quot;http://www.improveit.com.br/xp/praticas/ciclo_semanal&quot; target=&quot;_blank&quot;&gt;ciclos semanais&lt;/a&gt;. Durante meu treinamento Certified ScrumMaster foi proposto sprints de 28 dias, pois facilita visualiza&amp;ccedil;&amp;atilde;o em termos de semanas. Al&amp;eacute;m desses, eu j&amp;aacute; tive oportunidade de trabalhar com sprints de 1 e 2 semanas. O que eu sugiro pra voc&amp;ecirc;: Experimente! S&amp;oacute; assim voc&amp;ecirc; vai ser capaz de dizer o que &amp;eacute; apropriado para cada ocasi&amp;atilde;o. No mais, eu s&amp;oacute; posso citar alguns pontos que devem ser levados em considera&amp;ccedil;&amp;atilde;o para a sua decis&amp;atilde;o:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Escolha uma dura&amp;ccedil;&amp;atilde;o a qual seja agrad&amp;aacute;vel trabalhar, tal que a equipe consiga manter um &lt;a title=&quot;What is Extreme Programming?&quot; href=&quot;http://www.xprogramming.com/xpmag/whatisxp.htm#sustainable&quot; target=&quot;_blank&quot;&gt;ritmo sustent&amp;aacute;vel&lt;/a&gt;. Sprints muito longos podem levar &amp;agrave; procrastina&amp;ccedil;&amp;atilde;o (&lt;a title=&quot;Sindrome do Estudante&quot; href=&quot;http://pt.wikipedia.org/wiki/Procrastina%C3%A7%C3%A3o&quot; target=&quot;_blank&quot;&gt;S&amp;iacute;ndrome do Estudante&lt;/a&gt;). J&amp;aacute; sprints muito curtos conseguem ser bem estressantes quando algum imprevisto acontece;&lt;/li&gt;
&lt;li&gt;Requisitos mudam com freq&amp;uuml;&amp;ecirc;ncia (i.e., o cliente muda os planos constantemente ou &amp;eacute; incapaz de especificar com clareza o que deseja). Se for pra algo dar errado, que seja agora e n&amp;atilde;o daqui 15 dias. Ou seja, quanto antes voc&amp;ecirc; perceber que esta no caminho errado, o esfor&amp;ccedil;o para voltar atr&amp;aacute;s &amp;eacute; menor. E voc&amp;ecirc; s&amp;oacute; conhece esse caminho a partir do feedback, o que (geralmente) acontece mais frequentemente em sprints curtos;&lt;/li&gt;
&lt;li&gt;Semelhante as incertezas do cliente, deve-se ponderar as incertezas da equipe. Pois esta pode ser incapaz de dizer o quanto consegue trabalhar por itera&amp;ccedil;&amp;atilde;o ou desconhece de aspectos t&amp;eacute;cnicos do projeto;&lt;/li&gt;
&lt;li&gt;Da mesma forma que os requisitos podem mudar, o mesmo pode acontecer com suas prioridades. O seu tempo de resposta para eventuais mudan&amp;ccedil;as esta intimamente ligado &amp;agrave; dura&amp;ccedil;&amp;atilde;o dos sprints;&lt;/li&gt;
&lt;li&gt;Prepara&amp;ccedil;&amp;atilde;o (overhead) para os sprints. Suponha que antes de cada sprint todo o sistema precise passar por uma bateria de testes, ou que todo desenvolvedor deva reinstalar seu sistema e ambiente de desenvolvimento por medidas de seguran&amp;ccedil;a da empresa. Sem d&amp;uacute;vida sprints curtos n&amp;atilde;o s&amp;atilde;o a melhor escolha nesse caso. O ideal seria reduzir ou eliminar estes impedimentos, mas nem sempre isso &amp;eacute; poss&amp;iacute;vel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bem, se voc&amp;ecirc; tinha d&amp;uacute;vidas com rela&amp;ccedil;&amp;atilde;o o tamanho dos seus sprints, espero esses t&amp;oacute;picos sirvam como ponto de partida para uma poss&amp;iacute;vel mudan&amp;ccedil;a. Mas n&amp;atilde;o esque&amp;ccedil;a que at&amp;eacute; mesmo as mudan&amp;ccedil;as visando melhorias t&amp;ecirc;m seus efeitos colaterais. Portanto, uma vez definida uma dura&amp;ccedil;&amp;atilde;o apropriada para seus sprints, respeite esse valor, pois s&amp;oacute; assim voc&amp;ecirc; ser&amp;aacute; capaz de manter um ritmo (velocidade) de trabalho.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inspect and Adapt! &lt;/strong&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TDD em: O que testar?</title>
   <link href="http://horewi.cz/tdd-em-o-que-testar"/>
   <updated>2007-10-04T00:00:00-07:00</updated>
   <id>http://horewi.cz/tdd-em-o-que-testar</id>
   <content type="html">&lt;p&gt;Quando comecei a implantar desenvolvimento guiado por testes (&lt;a title=&quot;Tudo sobre TDD&quot; href=&quot;http://dojofloripa.wordpress.com/2007/09/10/tudo-sobre-tdd/&quot;&gt;TDD&lt;/a&gt;) na empresa em que trabalhava, tive a sorte de fazer parte de uma equipe de desenvolvedores bastante competente. Com apenas uma apresenta&amp;ccedil;&amp;atilde;o de poucos minutos e duas semanas de pr&amp;aacute;tica, quase todos j&amp;aacute; conseguiram captar que a ess&amp;ecirc;ncia do TDD n&amp;atilde;o &amp;eacute; apenas valida&amp;ccedil;&amp;atilde;o de c&amp;oacute;digo, mas tamb&amp;eacute;m a especifica&amp;ccedil;&amp;atilde;o de determinada funcionalidade.&lt;/p&gt;
&lt;p&gt;Tive apenas um caso em especial. Depois de algumas sess&amp;otilde;es de &lt;a title=&quot;Pair programming&quot; href=&quot;http://en.wikipedia.org/wiki/Pair_programming&quot;&gt;programa&amp;ccedil;&amp;atilde;o em par&lt;/a&gt; passei o teclado para o companheiro. Ele virou pra mim e disse: &amp;ldquo;T&amp;aacute;, e agora?&amp;rdquo;. N&amp;oacute;s j&amp;aacute; t&amp;iacute;nhamos discutidos anteriomente o contexto da funcionalidade, mas mesmo assim ele estava repleto de d&amp;uacute;vidas sobre o que realmente implementar&lt;/p&gt;
&lt;p&gt;Para tentar esclarecer um pouco as d&amp;uacute;vidas, fiz uma breve pesquisa na bibliografia e cheguei nos conceitos &lt;strong&gt;Right-BICEP&lt;/strong&gt; e &lt;strong&gt;CORRECT&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Right&lt;/strong&gt; &amp;ndash; Are the results &lt;strong&gt;right&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Dados valores de entrada e seus respectivos valores de sa&amp;iacute;da, verifica-se se a implementa&amp;ccedil;&amp;atilde;o esta de acordo, ou seja, se os resultados est&amp;atilde;o certos.&lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B&lt;/strong&gt; &amp;ndash;  Are all  the &lt;strong&gt;boundary&lt;/strong&gt; conditions &lt;strong&gt;CORRECT&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Verificar se os valores est&amp;atilde;o dentro do dom&amp;iacute;nio, dos limites aceit&amp;aacute;veis. Por exemplo, uma valida&amp;ccedil;&amp;atilde;o de preenchimento de um campo, ou ainda se este foi preenchido na formata&amp;ccedil;&amp;atilde;o adequada. Veja abaixo a descri&amp;ccedil;&amp;atilde;o do acr&amp;ocirc;nimo CORRECT, que descreve algumas condi&amp;ccedil;&amp;otilde;es de limites. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;I&lt;/strong&gt; &amp;ndash;  Can  you check &lt;strong&gt;inverse&lt;/strong&gt; relationships?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Alguns m&amp;eacute;todos podem ser verificados aplicando a sua l&amp;oacute;gica inversa. Por exemplo, para verificar o resultado de uma divis&amp;atilde;o, podemos comparar o dividendo com a multiplica&amp;ccedil;&amp;atilde;o do divisor com o quociente, adicionado ao resto. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C&lt;/strong&gt; &amp;ndash; Can you &lt;strong&gt;cross-check&lt;/strong&gt; results usings other means?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Semelhante a rela&amp;ccedil;&amp;atilde;o inversa, podemos verificar os resultados por outros meios. Podemos certificar o sucesso de uma inser&amp;ccedil;&amp;atilde;o de uma elemento em um vetor, verificando se o tamanho deste antes da inser&amp;ccedil;&amp;atilde;o e acrescido de um, &amp;eacute; igual o tamanho depois da inser&amp;ccedil;&amp;atilde;o &lt;em&gt;(1 + Ni = Ni+1)&lt;/em&gt;. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;E&lt;/strong&gt; &amp;ndash; Can you force &lt;strong&gt;error&lt;/strong&gt; conditions to happen?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Verificar como a aplica&amp;ccedil;&amp;atilde;o se comporta em situa&amp;ccedil;&amp;otilde;es adversas. Podemos for&amp;ccedil;ar um erro simples, com uma passagem de par&amp;acirc;metros incorreta, por exemplo. Mas n&amp;atilde;o podemos esquecer dos outros diversos poss&amp;iacute;veis problemas do dia-a-dia. Uma falha na comunica&amp;ccedil;&amp;atilde;o, espa&amp;ccedil;o em disco que se acaba, mem&amp;oacute;ria insuficiente, etc. Uma maneira de testar isso &amp;eacute; a utiliza&amp;ccedil;&amp;atilde;o de objetos Mock?. Mas isso j&amp;aacute; &amp;eacute; pano para outra manga =) &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P&lt;/strong&gt; &amp;ndash; Are &lt;strong&gt;performance&lt;/strong&gt; characteristics within bounds?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Nesse caso n&amp;atilde;o queremos testar o desempenho em si, mas sim se a curva de desempenho se mant&amp;eacute;m est&amp;aacute;vel, mesmo variando os cen&amp;aacute;rios. Suponha que os testes de uma busca em um vetor de tamanho &lt;em&gt;N&lt;/em&gt; passam em tempo &lt;em&gt;t&lt;/em&gt;. E se agora o vetor for de tamanho &lt;em&gt;N+M&lt;/em&gt;, os testes continuam passando em tempo &lt;em&gt;t+m&lt;/em&gt;? &lt;/dd&gt; &lt;/dl&gt;
&lt;p&gt;Como muitos dos problemas aparecem  na verifica&amp;ccedil;&amp;atilde;o das entradas e sa&amp;iacute;das, &amp;eacute; importante ter bem definido o seu dom&amp;iacute;nio, ou limites (boundary). Felizmente temos mais uma ferramenta para nos ajudar nessa defini&amp;ccedil;&amp;atilde;o.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C&lt;/strong&gt;onformance &amp;ndash; Does the value conform to an expected format?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Verifica se o valor em quest&amp;atilde;o esta de acordo com o formato estabelecido. Por exemplo, um CPF ou CNPJ, ou ainda uma estrutura mais complexa como uma &amp;aacute;rvore bin&amp;aacute;ria. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;O&lt;/strong&gt;rdering &amp;ndash; Is the set of values ordered or unordered as appropriate?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Diz respeito a ordena&amp;ccedil;&amp;atilde;o dos valores. Suponha os processos de uma cafeteira (bom exemplo!): colocarFiltro(), colocarPo(), colocarAgua(), servirCafe(). Esses processos necessariamente precisam estar nessa ordem, caso contr&amp;aacute;rio ningu&amp;eacute;m vai conseguir beber o valor de sa&amp;iacute;da. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;R&lt;/strong&gt;ange &amp;ndash; Is the value within reasonable minimum and maximum values?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Dado valor deve estar dentro do dom&amp;iacute;nio. Por exemplo, o preenchimento do ano de nascimento em um formul&amp;aacute;rio [1900,2007]. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;R&lt;/strong&gt;eference &amp;ndash; Does the code reference anything external that isn&amp;rsquo;t under direct control of the code itself?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Verificar se um cen&amp;aacute;rio referencia ou depende de outro fora do seu escopo. Suponha um portal de compras. Antes de adicionar qualquer produto ao carrinho, o usu&amp;aacute;rio deve ter iniciado uma sess&amp;atilde;o (efetuado login). Existem pr&amp;eacute; e p&amp;oacute;s-condi&amp;ccedil;&amp;otilde;es que devem ser satisfeitas para passar o teste. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;E&lt;/strong&gt;xistence &amp;ndash; Does the value exist (e.g., is non-null, nonzero, present in a set, etc.)?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;O teste mais intuitivo, acho. Verificar e um determinado valor de fato existe. Se certo par&amp;acirc;metro foi preenchido. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C&lt;/strong&gt;ardinality &amp;ndash; Are there exactly enough values?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Outro simples tamb&amp;eacute;m. Se a cardinalidade, quantidade dos par&amp;acirc;metros passados &amp;eacute; suficiente. &lt;/dd&gt; &lt;/dl&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;T&lt;/strong&gt;ime (absolute and relative) &amp;ndash; Is everything happening in order? At the right time? In time?&lt;/li&gt;
&lt;/ul&gt;
&lt;dl&gt; &lt;dd&gt;Devemos verificar se  execu&amp;ccedil;&amp;atilde;o de diversos processos em ordem. Cada um executando no momento certo. Lembra do exemplo da cafeteira? Tamb&amp;eacute;m se aplica aqui. Eu disse que era um bom exemplo =). Voc&amp;ecirc; tamb&amp;eacute;m pode imaginar uma linha de produ&amp;ccedil;&amp;atilde;o. &lt;/dd&gt; &lt;/dl&gt;
&lt;p&gt;Acho que isso &amp;eacute; um bom come&amp;ccedil;o. Mas gostaria de deixar bem claro que isso n&amp;atilde;o se trata de um guia, muito menos de uma receita de bolo. S&amp;atilde;o apenas alguns lembretes para facilitar e aprimorar a implementa&amp;ccedil;&amp;atilde;o dos seus testes. Caso voc&amp;ecirc; tenha se interessado neste t&amp;oacute;pico e queira a vers&amp;atilde;o &lt;em&gt;in extenso&lt;/em&gt;, voc&amp;ecirc; DEVE ler &lt;a style=&quot;opacity: 1;&quot; title=&quot;Pragmatic Unit Testing in Java with JUnit&quot; href=&quot;http://www.amazon.com/Pragmatic-Unit-Testing-Java-JUnit/dp/0974514012/ref=pd_bbs_sr_1/102-9513108-4139315?ie=UTF8&amp;amp;s=books&amp;amp;qid=1191443706&amp;amp;sr=1-1&quot;&gt;Pragmatic Unit Testing in Java with JUnit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Feliz TDD!&lt;/p&gt;
</content>
 </entry>
 
 
</feed>

