tag:blogger.com,1999:blog-46717213679229916832024-02-20T15:11:38.454+01:00Awesome Incremented.Building small increments of awesomenessMarcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-4671721367922991683.post-57013393591621323492016-01-24T14:42:00.000+01:002016-03-05T16:51:11.468+01:00Fluently testing your Autofac configurationGiven the popularity of the <a href="http://autofac.org/">Autofac</a> IoC container, we were surprised that there seemed to be no public library that supported testing your Autofac configuration.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Cafgvqgm2lBPH2HFlqomAZuNUEmHwz-q-9NkHWqtYZlg6WEa3K_Fl4pkqFILYZEcN7kYg5R__Tb4Pu8QYxj7VvGwUglrQ0uQK86EhGnmsnTrE1rseDT59jJWngaO6QTN3CJY-SyCa_Q/s1600/best+plan+fail+integration+testing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2Cafgvqgm2lBPH2HFlqomAZuNUEmHwz-q-9NkHWqtYZlg6WEa3K_Fl4pkqFILYZEcN7kYg5R__Tb4Pu8QYxj7VvGwUglrQ0uQK86EhGnmsnTrE1rseDT59jJWngaO6QTN3CJY-SyCa_Q/s320/best+plan+fail+integration+testing.png" width="320" /></a></div>
<br />
<a name='more'></a><br />
Well now there is <a href="https://github.com/awesome-inc/FluentAssertions.Autofac">FluentAssertions.Aufofac</a> which supports test the DI configuration like this<br />
<br />
<pre lang="csharp"> container.Should().Have().Registered<SuperCoolService>()
.AsSelf()
.As<ICoolService>()
.Singleton();
container.Should().Have().Registered(superCoolInstance);
container.Should().Have().Registered<OtherCoolService>()
.Named<ICoolService<("prettyCool");
container.Should().Have().NotRegistered<UncoolService>("uncool");
</pre>
<br />
And not even registration but also resolving which asserts that you did not forget any dependency<br />
<br />
<pre lang="csharp"> container.Should().Resolve<ICoolService>().As<SuperCoolService>()
.AutoActivate();</pre>
<br />
But maybe there is just no need to test Dependency Injection? Let's see...<br />
<br />
<h3>
<a href="https://www.blogger.com/blogger.g?blogID=4671721367922991683#why">Why test your IoC configuration in the first place?</a></h3>
<br />
In general, the more you apply <a href="http://martinfowler.com/articles/injection.html">Dependency Injection (DI)</a> the easier becomes unit testing and <a href="https://en.wikipedia.org/wiki/Test-driven_development">Test-driven Development (TDD)</a>.<br />
<br />
This is because the complexity of constructing all dependencies is shifted to the so called <a href="http://blog.ploeh.dk/2011/07/28/CompositionRoot/">Composition Root</a>, i.e. the place where you "wire up" and configure all your dependencies.<br />
Undoubtedly, the best way to do this is by using some <a href="http://martinfowler.com/articles/injection.html">Inversion of Control (IoC)</a> container.<br />
<br />
With an application growing in complexity, there is also growing need to organize and test the IoC configuration.<br />
<br />
<b>Here is the usual story:</b> During release sprints we typically develop features in parallel that form complete workflows (think <a href="https://www.mountaingoatsoftware.com/blog/stories-epics-and-themes">epics or themes</a>, if you will). While carving these out, we mock out dependencies to the other features. This way everyone can move forward without needing the other features completed.<br />
<br />
For example, you're designing the coolest recommendation view on the planet. While your buddy is on the recommendation service on the backend, you will register a mock, i.e.<br />
<br />
<pre lang="csharp"> ...
builder.RegisterType<MockRecommendations>().As<IGetRecommendations>();
// builder.RegisterType<RecommendationService>().As<IGetRecommendations>();
...</pre>
<br />
Once your buddy gives thumbs up for integration testing you switch to the real thing. Finally, you finish and move on to the next feature.<br />
<br />
So far, so good. But then, a <b>critical issue</b> with your view (or likewise viewmodel, controller) rises in production. No problem, you go for the hotfix, switch back to your mock so you can better and quicker reproduce the problem. You fix the problem but then, <b>you forget to switch back from the mock to the productive recommendation service -</b> which gives you a serious <a href="https://en.wikipedia.org/wiki/Facepalm">#facepalm</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/uSvJaYxRoB4/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/uSvJaYxRoB4?feature=player_embedded" width="320"></iframe></div>
<br />
Wouldn't it be nice if there was a test saving you from breaking the release next time? Well, now there is.<br />
<br />
<h3>
<a href="https://www.blogger.com/blogger.g?blogID=4671721367922991683#fluent-api">Fluent interfaces and readable code</a></h3>
<br />
Most of the time, we prefer using this stack<br />
<ul>
<li><a href="http://autofac.org/">Autofac</a> for wiring up DI,</li>
<li><a href="http://nsubstitute.github.io/">NSubstitute</a> for mocking and</li>
<li><a href="http://www.fluentassertions.com/">FluentAssertions</a> for extremely readable tests that naturally explain when failing.</li>
</ul>
There is nothing special about this choice. But there is at least one thing these libraries have in common: They all share a profound intent on improving accessibility and readability by providing a <a href="https://en.wikipedia.org/wiki/Fluent_interface">fluent API</a>.<br />
<br />
In the rare case that you - as a developer - never quoted that <i>"Code is read much more often than it is written"</i> and are wondering why you should thrive for readable code in the first place, then here is a hand-picked selection of classic references that we found to be helpful<br />
<ul>
<li><a href="http://blogs.msdn.com/b/peterhal/archive/2006/01/04/509302.aspx">What Do Programmers Really Do Anyway? (Peter Hallam, 2006)</a></li>
<li><a href="http://blog.codinghorror.com/when-understanding-means-rewriting/">When Understanding means Rewriting (Jeff Atwood, 2006)</a></li>
<li><a href="https://blogs.msdn.microsoft.com/oldnewthing/20070406-00/?p=27343">Code is read much more often than it is written, so plan accordingly (R.Chen - MSFT, 2007)</a></li>
<li><a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin et al., 2008)</a></li>
<li><a href="http://lingpipe-blog.com/2009/10/15/the-futility-of-commenting-code/">The Futility of Commenting Code (Bob Carpenter, 2009)</a></li>
<li><a href="http://blog.codinghorror.com/learn-to-read-the-source-luke/">Learn to Read the Source, Luke (J.Atwood 2012)</a></li>
<li><a href="http://siderite.blogspot.com/2012/04/refactoring-improving-design-of.html">Review of M.Fowlers classic "Refactoring: Improving the Design of Existing Code" (2012)</a> </li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://blog.codinghorror.com/learn-to-read-the-source-luke/"><img alt="Learn to Read the Source" border="0" src="http://blog.codinghorror.com/content/images/uploads/2012/04/6a0120a85dcdae970b016765373659970b-800wi.jpg" height="180" width="320" /></a></div>
<br />
<h3>
</h3>
Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-90382869573851536952015-12-11T16:21:00.000+01:002016-01-24T12:53:23.924+01:00Advanced NCrunch: Isolating tests<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqKlW0zctpJG6tL4jVI9FbuwqNGha8aAvkuJiDyAR1TUKg8BUWCg31S2VSHEUbn4gEyVij4U9nCIT6tUU-xeCnputnHFAVddN7puYXpaNytPcwxLKXYX0JSv5KPZCzP8uQRDvWcxgTHG0/s1600/pablo+%25281%2529.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqKlW0zctpJG6tL4jVI9FbuwqNGha8aAvkuJiDyAR1TUKg8BUWCg31S2VSHEUbn4gEyVij4U9nCIT6tUU-xeCnputnHFAVddN7puYXpaNytPcwxLKXYX0JSv5KPZCzP8uQRDvWcxgTHG0/s400/pablo+%25281%2529.png" width="400" /></a></div>
<br />
I am constantly amazed on how far you can push the frontiers of automated testing in order to reduce blind spots and mitigate software risks.<br />
<a name='more'></a><br />
For instance, my friend Thomas (<a href="https://twitter.com/ThomasMentzel">@ThomasMentzel</a>) currently works on automating screenshots for <a href="https://speakerdeck.com/awesomeincremented/how-to-make-a-better-fm">continuous documentation</a> in the context of a standard test runner like NUnit. I am sure he will post about this soon.<br />
<br />
This is just one example on how to easily extend automated testing on aspects most people would not consider for unit testing. And yeah, right - testing behaviour on external resources like the file system (<a href="https://github.com/tathamoddie/System.IO.Abstractions">tathamoddie/System.IO.Abstractions</a>), the registry (<a href="https://github.com/jozefizso/SystemWrapper">jozefizso/SystemWrapper</a>), etc. belongs to integration testing and is outside the scope of unit testing, strictly spoken.<br />
<br />
However, test runner frameworks like <i>NUnit, xUnit</i>, etc. combined with continuous testing tools like <i>NCrunch</i> are so powerful & easy to use that i don't see any reason why not to formulate these kind of tests as simple unit tests, e.g. using the <code>Explicit</code> or <code>Category</code> attribute.<br />
<br />
Today, i want to share a use case for some lesser known features of NCrunch that allow you to tweak "how isolated" your tests run.<br />
<br />
A while ago, i posted about my experiences on <a href="http://awesome-incremented.blogspot.de/2015/05/nets-bad-relatives-on-native.html">handling native dependencies</a> re-introducing an ancient trick, i.e. modifying your process environment by injecting a customized <code>PATH</code> environment variable in the application bootstrapping phase.<br />
<br />
Until recently, i neither needed to modify nor test the bootstrapper code. But then a change request came in, that forced me to touch it. In this particular case, we wanted to simplify Oracle connection strings by using <a href="http://www.orafaq.com/wiki/Tnsnames.ora">tnsnames.ora</a> which required to optionally override the <code>TNS_ADMIN</code> environment variable as well.<br />
<br />
Following TDD's <a href="http://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html">red-green-refactor cycle</a> i wanted to start a "red" - i.e. failing - test. But how can you isolate <code>System.Environment</code> without affecting all other test cases?<br />
<br />
This is where the <a href="https://www.ncrunch.net/documentation/reference_runtime-framework_isolated-attribute">NCrunch IsolatedAttribute</a> comes in.
The cool thing about it is that you don't even need to include a reference to the NCrunch framework, because Remco Mulder (<a href="https://twitter.com/remcomulder">@remcomulder</a>), NCrunch's main developer, made it super easy to use it.<br />
<br />
Here is what the - now "green" - test looks like. It includes testing that the bootstrapper logs a bit about what he does.<br />
<br />
Needless to say, that the implementation did not require any more manual testing.
<br />
<br />
<pre lang="csharp">[Test(Description = "#<issue>: simple oracle db connection (using TNS_ADMIN)")]
// Since we check that environment variable will be set correctly,
// we need to isolate this test
// cf.: http://www.ncrunch.net/documentation/v1/reference_runtime-framework_isolated-attribute
[NCrunch.Framework.Isolated]
[Category("Integration")]
public void Bootstrap_oracle_and_tns_admin()
{
var config = new Configuration();
config.PathToOracleClient
.Should().Be("%ORACLE_HOME%", "should be default");
config.TnsAdmin.Should().Be("%ORACLE_HOME%", "should be default");
var expandedOracleClientPath = Environment
.ExpandEnvironmentVariables(config.PathToOracleClient);
var expandedTnsAdmin = Environment
.ExpandEnvironmentVariables(config.TnsAdmin);
Environment.ExpandEnvironmentVariables("%PATH%")
.Should().NotContain(expandedOracleClientPath);
Environment.ExpandEnvironmentVariables("%TNS_ADMIN%")
.Should().NotBe(expandedTnsAdmin);
// cf. github NEdifis
using (var ttl = new TestTraceListener())
{
var sut = new OracleModule(config);
// // extension method, cf. github AutoFac.TestingHelpers
sut.GetContainer();
var infos = ttl.MessagesFor(TraceLevel.Info).ToList();
infos.Should().Contain(
$"Using Oracle connection string: '{sut.OracleConnectionString}'.");
infos.Should().Contain(
$"Using '{expandedOracleClientPath}' to lookup Oracle native libraries.");
infos.Should().Contain(
$"Using TNS_ADMIN='{expandedTnsAdmin}' to lookup 'tnsnames.ora'.");
}
Environment.ExpandEnvironmentVariables("%PATH%")
.Should().Contain(expandedOracleClientPath);
Environment.ExpandEnvironmentVariables("%TNS_ADMIN%")
.Should().Be(expandedTnsAdmin);
}</issue></pre>
<div id="spoon-plugin-kncgbdglledmjmpnikebkagnchfdehbm-2" style="display: none;">
</div>
Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-53390304642180915232015-12-11T12:35:00.000+01:002015-12-14T11:24:24.323+01:00"dev.talk" or how we started to change the company culture<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifbyMNjDtxSwlqsSLBaOH6dMZd1WLj63lQPF8vx2eASChpJoWjaRl4ZRQ5ffep2cSRWYeGRF9NOiZs07Iq14v7jBNgdcMV8cjH8Ro4qDZR_1zJjhyphenhyphenYl163ScjywFtjyxSD58vAR623Yas/s1600/How_does_open_source_affect_company_culture-_%25285497223174%2529_%25282%2529.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifbyMNjDtxSwlqsSLBaOH6dMZd1WLj63lQPF8vx2eASChpJoWjaRl4ZRQ5ffep2cSRWYeGRF9NOiZs07Iq14v7jBNgdcMV8cjH8Ro4qDZR_1zJjhyphenhyphenYl163ScjywFtjyxSD58vAR623Yas/s320/How_does_open_source_affect_company_culture-_%25285497223174%2529_%25282%2529.jpg" width="320" /></a></div>
<br />
For the past four months we have a <a href="http://awesome-incremented.blogspot.de/2015/09/devtalk-or-how-we-cheated-our-management.html" target="_blank">weekly dev.talk about mixed topics</a>. After a colleague of mine and I started to prepare and present these talks for a couple of weeks, we found some colleagues presenting topics as well.<br />
<a name='more'></a><br />
<br />
The following list gives an overview over the variation of the talks.<br />
<br />
<blockquote class="tr_bq">
7 Aug: <a href="https://speakerdeck.com/awesomeincremented/graph-databases-a-gentle-introduction" target="_blank">Graph Databases</a><br />
14 Aug: <a href="https://speakerdeck.com/awesomeincremented/the-twelve-factor-app" target="_blank">Twelve Factor App</a><br />
21 Aug: <a href="https://speakerdeck.com/awesomeincremented/productivity-and-self-management" target="_blank">Productivity and Self-management</a><br />
28 Aug: <a href="https://speakerdeck.com/awesomeincremented/wearables-oder-warum-soll-ich-10-dot-000-schritte-gehen" target="_blank">Wearables or why should I walk 10.000 steps a day (DE)</a><br />
4 Sep: <a href="https://speakerdeck.com/awesomeincremented/on-the-book-taming-text" target="_blank">Taming Text</a><br />
11 Sep: <a href="https://speakerdeck.com/awesomeincremented/open-source-as-chance-for-your-enterprise" target="_blank">Open Source as chance for your enterprise</a><br />
21 Sep: <a href="https://speakerdeck.com/awesomeincremented/introduction-to-gitversion" target="_blank">GitVersion</a><br />
25 Sep: <a href="https://speakerdeck.com/awesomeincremented/on-the-book-lean-enterprise" target="_blank">Lean Enterprise</a><br />
2 Oct: Happiness@Work (colleague)<br />
9 Oct: <a href="https://speakerdeck.com/awesomeincremented/how-to-make-a-better-fm" target="_blank">Don't want to write documentation?</a><br />
15 Oct: <a href="http://blackbeltprogrammer.blogspot.de/2015/11/7-steps-to-become-superhero.html" target="_blank">7 steps to become a super hero</a><br />
23 Oct: <a href="https://speakerdeck.com/awesomeincremented/hands-on-kanban" target="_blank">Kanban in practice</a><br />
29 Oct: Load tests with JMeter (colleague)<br />
05 Nov: <a href="https://speakerdeck.com/awesomeincremented/the-nuget-ecosystem" target="_blank">NuGet Ecosystem</a><br />
12 Nov: <a href="https://speakerdeck.com/awesomeincremented/an-introduction-to-clean-code-developer" target="_blank">Self-Improcement as Clean Code Developer</a><br />
20 Nov: Drones! (colleague)<br />
26 Nov: <a href="https://speakerdeck.com/awesomeincremented/git-is-everywhere-real-world-use-cases" target="_blank">Git in practice</a><br />
4 Dec: <a href="https://speakerdeck.com/awesomeincremented/data-science-101-an-overview-medley">DataScience</a><br />
<div>
11 Dec: Surprise BBQ</div>
</blockquote>
...and we have already two talks scheduled for next year -from other colleagues.<br />
<br />
In the end we found more and more colleagues presenting something... technical and non technical. The colleagues started to accept, participate and became involved into this idea of weekly talks.<br />
<br />
But there are a lot more other advantages.<br />
<br />
<b>Management attention</b><br />
<br />
The management started to realize that it makes sense to have an institution like "dev.talk" to improve the business. Projects start to use tools we present like GitVersion or use management techniques like kanban boards (in addition to mantis tickets).<br />
<br />
<b>Talk more to each other</b><br />
<br />
Depending on the kind of talk (drones, jmeter) we got in touch with the daily work of our colleagues. Why did we bought a drone for the company? How do we do load testing on one of our products? And especially how do the others use git or write documentation? Now we and the others know!<br />
<br />
<b>Self improvement</b><br />
<br />
We realized that out presentation skills improved and especially the time management during our presentations.<br />
<br />
<br />
<div style="text-align: center;">
<b><i>It was a lot of work to create these talk and prepare everything.</i></b></div>
<div style="text-align: center;">
<b><i>But due to the fact, we made all of our work in our spare-time,</i></b></div>
<div style="text-align: center;">
<b><i>we could do this open source and use this for "self marketing".</i></b></div>
<br />
<div id="spoon-plugin-kncgbdglledmjmpnikebkagnchfdehbm-2" style="display: none;">
</div>
Anonymoushttp://www.blogger.com/profile/03349722314831314332noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-9212813668135168412015-09-03T06:32:00.003+02:002015-09-06T07:43:28.298+02:00Review: NBP116 – How to Master the Habits of Our Everyday Lives, with Gretchen RubinI just love the Internet because it makes expanding your horizon and knowledge increasingly easy for everyone. Each followed link may open up a new door. So let me tell you how i got here:<br />
<br />
<a name='more'></a><br />
Some weeks ago, i got to know Rory Vaden via his insightful TEDx talk on <a href="https://www.youtube.com/watch?v=y2X7c9TUQJ8">"How to multiply your time"</a> on YouTube. I wanted to get his book <a href="http://www.amazon.de/Procrastinate-Purpose-Permissions-Multiply-Your/dp/0399170626">Procrastinate on Purpose</a> and started to follow some of Rorys inspiring content on Twitter.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/y2X7c9TUQJ8/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/y2X7c9TUQJ8?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
This led me to Chris Duckers <a href="http://www.chrisducker.com/podcast/">New Business Podcast</a> which mostly targets entrepreneurs as audience. Despite the fact that i am more a programmer or agile coach than an entrepreneur (yet) I like the podcast very much. Chris Ducker puts an energizing & refreshing voice on it together with loads of helpful tips.<br />
<br />
Today I listened to the current episode <a href="http://www.chrisducker.com/podcast/habits-everyday-lives-gretchen-rubin/">NBP116 – How to Master the Habits of Our Everyday Lives, with Gretchen Rubin</a> which kind of closed a cycle to me because i already knew Gretchen Rubin for her great book <a href="http://www.amazon.de/The-Happiness-Project-Aristotle-Generally/dp/0061583251">The Happiness Project</a>. I haven't read her new best-selling book <a href="https://gretchenrubin.com/books/before-after/before-after/">Better Than Before</a>, though<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.chrisducker.com/podcast/habits-everyday-lives-gretchen-rubin/"><img border="0" src="http://www.chrisducker.com/wp-content/uploads/2015/08/NBP116-Gretchen-Rubin-1024x475.png" height="148" width="320" /></a></div>
<br />
<br />
In case you ask yourself whether to go and listen to the show, i will make it easier for you and quickly summarize what i got from the episode:<br />
<br />
1. Chris asks Gretchen about what entrepreneurs can do to be "happier". As an example, many of them might report to be "always stressed out". This sounds precise but in fact is a vague phrase. Gretchen suggests that you cannot think about the solution until you <a href="http://gretchenrubin.com/happiness_project/2010/08/identify-the-problem/">identified the real problem</a>. There could be many reasons to be "stressed out". A very common example is to be "stressed" because of the constant distractions of a messed up workplace. The solution: Just clean up and remove all the stuff. Sounds trivial but definitely makes a difference.<br />
<br />
2. Another cause for entrepreneurs to feel "stressed out" is simply they work too much and sleep too less. Gretchen clearly states that if you rely on your brain then sleep is not optional. Well, "sleep more" sounds easy but maybe hard to achieve. So she give some examples on how to hack your habits the way you want them to. It basically comes down to make the good habits as convenient as possible to do while making the bad habits hard to do. Gretchen wrote a blog post on that which you can read <a href="https://gretchenrubin.com/happiness_project/2014/03/do-you-find-it-hard-to-turn-off-the-light-even-when-you-need-the-sleep/">here</a>.<br />
<br />
3. She points out that when forming habits it's important to understand whether you'r an <a href="https://www.psychologytoday.com/blog/the-happiness-project/201210/are-you-abstainer-or-moderator">Abstainer or Moderator</a>. Briefly, abstainers are "All or Nothing" people while moderators do better when they avoid obstacles and strict rules.<br />
<br />
4. Chris and Gretchen advance talking about loophole spotting. Gretchen identifies 10 categories of loopholes, one of her favorites being the <a href="https://gretchenrubin.com/happiness_project/2014/01/strategy-of-loophole-spotting-10-the-one-coin-loophole/">One-Coin loophole</a>. Another one is the <a href="http://gretchenrubin.com/happiness_project/2014/01/strategy-of-loophole-spotting-3-the-tomorrow-loophole/">Tomorrow</a> loophole which i also relate to <a href="https://en.wikipedia.org/wiki/Kairos">Kairos</a>, the ancient greek term for the "right moment" or "moment of opportunity" which Gunter Dueck explained so well in his book <a href="http://www.amazon.de/Das-Neue-seine-Feinde-durchsetzen/dp/359339717X">Das Neue und seine Feinde</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.de/Das-Neue-seine-Feinde-durchsetzen/dp/359339717X"><img border="0" src="http://ecx.images-amazon.com/images/I/51XPFrNiWaL._SX312_BO1,204,203,200_.jpg" height="320" width="201" /></a></div>
<br />
<br />
So the bottom line is: If you don't already haven't start "hacking" your habits now!Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-28352498700770098692015-09-02T09:43:00.001+02:002015-12-14T11:30:05.378+01:00"dev.talk" or how we cheated our management<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7PSrpFxlERqWYY5iNXKENuk1yfoQiE6PnbzehslRAsD3Q0RXkx1ilJEbByXrO8yE5iaqB_5IHPMlUPpWVXOtZGAGJLEnGjlwuUXlbZpDqhh-BD17RPHMo5W-MvRQWxDMkOm8NlR02XKY/s1600/shut-up-and-just-do-it-7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7PSrpFxlERqWYY5iNXKENuk1yfoQiE6PnbzehslRAsD3Q0RXkx1ilJEbByXrO8yE5iaqB_5IHPMlUPpWVXOtZGAGJLEnGjlwuUXlbZpDqhh-BD17RPHMo5W-MvRQWxDMkOm8NlR02XKY/s320/shut-up-and-just-do-it-7.png" width="274" /></a></div>
<br />
After I changed my job, I had to face the same old problem: I have to work for a project. I have to work 40 hours a week and each hour needs to be for a project.<br />
<a name='more'></a><br />
<br />
Lets assume I prepare a talk for four hours and ten colleagues attend the 30 minute talk. So the company "looses" 9 man hours. If the company would save 15 hours because of the knowledge sharing, they would not care. It is easy to estimate time costs but hard to proof these time savings. So <strong>no project, no talk, no knowledge sharing</strong>.<br />
<br />
So the only way to have talks and share knowledge is to sacrifice our spare time. But how to get my colleagues attending the talk, though they need to offer spare time as well? The solution is as simple as obvious. The speaker unfortunately offers his spare time to prepare the talk, but presents his talk during lunch break. We need to take a lunch break of at least 45 minutes, which is basically enough for a 30 minutes talk. And the colleagues can attend the talk, have their lunch during the talk and ask questions.<br />
<br />
A colleague of mine and I started to have talks every two weeks. Lately we started to have weekly talks and invited the entire company, including the management. Surprisingly the management attended as well as 15 up to 25 of our colleagues. After a few months we had a real success: Another colleague wanted to have a talk and share something and he offered a few topics.<br />
<br />
<strong>But why the effort and sacrifice spare time?</strong> Obviously we started to increase our value for the company especially for project managers and the management. On a second view we started to improve our presentation skills. But finally we could present our spare time studies and try to make the management invest into certain technology or knowledge -whereby we are the first-choice person to get the internal project ;). And at least with some non-technical topics, we even started to change internal processes (the first project uses a <a href="https://speakerdeck.com/awesomeincremented/productivity-and-self-management" target="_blank">Kanban board combined with pomodoro</a>).<br />
<br />
<div style="text-align: center;">
<strong><em>So be a good leader and make others follow you.</em></strong></div>
<div style="text-align: center;">
<strong><em>Share your knowledge and change the world.</em></strong><br />
<br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
P.S: How leadership should work ... <a href="http://kottke.org/13/05/leadership-lessons-from-the-dancing-guy" target="_blank">an explanation</a></div>
<br /></div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
P.P.S: Our slides can be <a href="https://speakerdeck.com/awesomeincremented" target="_blank">found here</a> (as long as they do not include too many "borrowed" slides)</div>
Anonymoushttp://www.blogger.com/profile/03349722314831314332noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-25145023178837777512015-06-30T08:47:00.000+02:002015-12-14T12:05:23.498+01:00Shipping tests along with production code<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZ-Tc8LT2PumVhOuiw05LWjQSfXcXxClR-KjgmU3AKAI5BuQQftjEHXkSUEDIfm9-1ooOBi8LevOc2JGhW3ceqgCosrGPV6O1EVYpgsNtEqiZ4w7K31ElItpQOyWbEV8_fsbqduMI2J0/s1600/pablo+%25281%2529.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfZ-Tc8LT2PumVhOuiw05LWjQSfXcXxClR-KjgmU3AKAI5BuQQftjEHXkSUEDIfm9-1ooOBi8LevOc2JGhW3ceqgCosrGPV6O1EVYpgsNtEqiZ4w7K31ElItpQOyWbEV8_fsbqduMI2J0/s320/pablo+%25281%2529.png" width="320" /></a></div>
<br />
<br />
With <a href="https://github.com/awesome-inc/NEdifis">NEdifis</a> we advocate putting tests right beside the code rather than into separate test projects. Both approaches have its pros and cons, yet the more popular still seems to be putting tests <a href="http://www.bryancook.net/2008/05/tdd-tips-unit-test-namespace.html">into a separate test project</a>, see for example <a href="http://blog.ploeh.dk/2013/06/17/where-to-put-unit-tests/">Mark Seemann: Where to put unit tests</a> or <a href="http://stackoverflow.com/questions/347156/do-you-put-unit-tests-in-same-project-or-another-project/554732">StackOverflow: Do you put unit tests in same project or another project?</a> The most common reasons for separated test projects are:<br />
<a name='more'></a><ol>
<li>According to TDD, tests are <a href="http://blog.ploeh.dk/2011/11/10/TDDimprovesreusability/">the first client of your API</a>, i.e. accessing the API from outside gives early feedback and should therefore improve your API design for intended users.</li>
<li>The additional testing code requires more disk space and may increase startup or loading time. You definitely want to avoid this on low resource hardware like mobile devices or embedded systems system.</li>
<li>The testing code can make your component vulnerable so you might need to think more about security concerns.</li>
</ol>
The most common reasons to keep code and tests together:<br />
<ol>
<li>Internal helper code can be tested a lot easier. The usual workarounds with <code><a href="http://msdn.microsoft.com/de-de/library/7c5ka91b(v=vs.90).aspx">internal</a></code> and <a href="http://msdn.microsoft.com/de-de/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx">InternalsVisibleTo</a> (corresponding <a href="http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html">Package scope in Java</a>), conditional compilation (e.g. only DEBUG) and even test-specific subclassing are way more prone to rework.</li>
<li>Completely separated test bases are yet a lot worse in terms of rework required to keep code and tests in sync. Tests in a separate solution/workspace or worse yet, in a different git repository, a different programming language/framework, a different whatever... just don't age well with your code. On the contrary, experience shows that tests are the more effective in minimizing implementation risk the closer they are to the code to be tested, cf. <a href="http://lmgtfy.com/?q=test+early+and+often">test early and often (lmgtfy)</a>. Only then, tests can evolve quickly with the code. Otherwise, the chance of your tests diverging from the code is increased. This is the main reason why commercial testing software like <a href="http://de.wikipedia.org/wiki/QF-Test">QF-Test</a> or <a href="http://de.wikipedia.org/wiki/Ranorex">Ranorex</a> is less effective.</li>
<li>The additional test code does increase the final assembly size. But unless you are counting bytes this is often negligible. The startup time is not affected since testing code and frameworks don't need to be loaded (e.g. NUnit) unless you do a test run. In fact, you can even skip shipping testing framework assemblies to save some kilobytes.</li>
<li>Shipping testing code (unit, integration and acceptance tests) greatly documents the state of implementation. It represents the requirements specification - not written on paper but directly executable for the customer. It is vital that you manage to keep the abstraction level of the tests very close to the specified requirements. This is of course easier for a technical project or customers with a strong technical background. In early 2012, i met Daniel Fischer (@lennybacon) who told me about <a href="http://www.lennybacon.com/post/2010/05/27/docx2unittest">DocX2 Unit Test</a> which aims to reduce the media barrier between customer and developer. Great idea!</li>
</ol>
<div>
A very small point i want to add to this list, that hasn't been mentioned before AFAIK, is a pragmatic one: Keeping code and testing code together simplifies the steps needed for automated <code>compile & test</code> which is fundamental for <a href="http://de.wikipedia.org/wiki/Kontinuierliche_Integration">Continuous Integration</a>, i.e:</div>
<ul>
<li>Compiling the main project also compiles all its tests. No need for a sepaerate compile instruction, i.e.</li>
<ul>
<li>build MyProject.csproj</li>
<li><strike>build MyProject.Tests.csproj</strike></li>
<li>build MyLib.csproj</li>
<li><strike>build MyLib.Tests.csproj</strike></li>
</ul>
<br />
<li>All relevant test binaries are compiled to the output folder of the main project. So, parameterizing the test or coverage runner from a build job is simple ("run tests/coverage for all assemblies in folder"). Build job maintenance is also reduced, e.g. you never need to track project naming changes in your build job - except for the main project, of course ;-).</li>
</ul>
These observations mainly result from our experience with .NET and CI servers like Jenkins, AppVeyor or TeamCity. Instead of, say 10 build steps there is now only one.<br />
<div id="spoon-plugin-kncgbdglledmjmpnikebkagnchfdehbm-2" style="display: none;">
</div>
Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-63742033586691912912015-06-10T11:29:00.001+02:002015-06-30T08:59:23.075+02:00"To throw or not to throw": Asserting exceptions on tasks with async/awaitFor testing exceptional behaviour i like using FluentAssertions <a href="https://github.com/dennisdoomen/fluentassertions/wiki#exceptions">Invoking</a> extensions. However, i noticed that using this with async/await seems not to be supported and <a href="https://github.com/dennisdoomen/fluentassertions/issues/46">requires unelegant rewriting</a> (Please, prove me wrong on this). However, using <a href="http://www.kunal-chowdhury.com/2015/01/csharp-6-await-statement.html">C# 6 await in try-catch</a> this is now very simple to do:
<br />
<br />
<a name='more'></a><br /><br />
<pre>[TestFixture]
class ThrowTest
{
[Test]
public async void Task_should_throw()
{
await TestTask().ShouldThrow<notimplementedexception>();
}
private static async Task TestTask()
{
throw new NotImplementedException();
}
}
static class AsyncTaskAssertExtensions
{
public static async Task ShouldThrow<texception>(this Task task,
string because = null)
where TException : Exception
{
try
{
await task;
Assert.Fail(because ?? $"The specified task was expected to throw '{typeof(TException).Name}', but no exception occured.");
}
catch (TException) { }
}
}
</texception></notimplementedexception></pre>
Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-4217887476264430502015-06-03T13:06:00.001+02:002015-06-30T09:01:36.302+02:00Reducing repetition in native wrappers using expression bodied membersWhenever wrapping legacy or native APIs in .NET i hate the verbosity of the code that needs to be written. APIs without a concept of exceptions are often designed returning error codes which requires results to be passed back per reference. In .NET this translates to using out-Parameters.<br />
<a name='more'></a> Here is an example taken from <a href="https://github.com/naudio/NAudio">NAudios</a> wrapper for the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd370802%28v=vs.85%29.aspx">Windows Core Audio API</a>, see <a href="https://github.com/naudio/NAudio/blob/master/NAudio/CoreAudioApi/MMDevice.cs#L224">here</a>.:<br />
<pre>public string ID
{
get
{
string result;
Marshal.ThrowExceptionForHR(deviceInterface.GetId(out result));
return result;
}
}</pre>
This usage pattern repeats all over the code base. Using the helper method <a href="https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.throwexceptionforhr%28v=vs.100%29.aspx">Marshal.ThrowExceptionForHR</a> already helps reducing lines but it is still not a one liner.<br />
<br />
Wouldn't it be nice to use C# 6 <a href="https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#expression-bodies-on-property-like-function-members">Expression Bodied Members</a> here? Of course, but the out-Parameter signature prevents the obvious refactoring path of reducing the code block to a one-liner using lambdas/delegates.<br />
<br />
It seems many folks still believe that <a href="http://stackoverflow.com/questions/1365689/cannot-use-ref-or-out-parameter-in-lambda-expressions">lambdas cannot be with out- and ref-Parameters</a> because <a href="https://msdn.microsoft.com/en-us/library/bb397687(v=vs.140).aspx">lambdas cannot directly capture out and refs</a>. Actually, this is quite simple to do. Here is what i came up with<br />
<pre>public string Id => MarshalEx.Get<string>(deviceInterface.GetId);</string></pre>
using<br />
<pre>static class MarshalEx
{
public delegate int FuncOut<t>(out T value);
public static T Get<t>(FuncOut<t> getter)
{
T result;
Marshal.ThrowExceptionForHR(getter(out result));
return result;
}
}</t></t></t></pre>
Pretty sweet: 9 lines reduced to a one-liner. Overall, this reduced the number of lines down to to 40% of its original size at the same time improving readability. So, less space for you bugs to hide!Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-11374162073268768012015-05-18T09:51:00.000+02:002015-06-30T09:02:51.381+02:00C# 6 in action: Null propagation appliedJust another nice everyday example on how C# 6 can reduce verbosity. In case you don't let ReSharper teach you, be sure to spend <a href="https://channel9.msdn.com/Series/ConnectOn-Demand/211">8 minutes on C# 6</a>.<br />
<br />
<a name='more'></a><br />
This is one of the more noteable of today's refactorings where <a href="https://msdn.microsoft.com/en-us/magazine/dn802602.aspx">null-propagation</a> was applied.<br />
<br />
Before:
<br />
<pre>private bool CurrentContextHasPlayer()
{
return _currentViewContext != null &&
_currentViewContext.AudioView != null &&
_currentViewContext.AudioView.AudioPlayer != null &&
_currentViewContext.AudioView.AudioPlayer.Player != null;
}</pre>
<br />
After:
<br />
<pre>private bool CurrentContextHasPlayer()
{
return _currentViewContext?.AudioView?.AudioPlayer?.Player != null;
}</pre>
<br />
You might argue that this is an instance of the <a href="http://blog.codinghorror.com/code-smells/">Feature Envy code smell</a> and maybe you would be right ;-)Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-36030525555621377932015-05-09T11:12:00.003+02:002015-12-14T11:33:42.943+01:00.NET's bad relatives: On native dependencies<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDf0lf1YeHM5H-ANC6ewKQNgxaBtQvPe7a-5ItzyyekepsPlhYw_A4okzO31PYC9NzCC5wiCybvyqfTuf6eKVDjvZ0AfD_McuYDQ4xD5hyhD-zEH0IceH-7lWLfhBJRmJrV1krei0427Y/s1600/pablo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDf0lf1YeHM5H-ANC6ewKQNgxaBtQvPe7a-5ItzyyekepsPlhYw_A4okzO31PYC9NzCC5wiCybvyqfTuf6eKVDjvZ0AfD_McuYDQ4xD5hyhD-zEH0IceH-7lWLfhBJRmJrV1krei0427Y/s320/pablo.png" width="320" /></a></div>
<br />
<br />
I have a love-hate relationship with native dependencies. As a developer i love quickly boosting my app with features from native code libraries using e.g. <a href="http://www.pinvoke.net/">P/Invoke</a>. However, when it comes to deployment we need to make sure that the native dlls will be 1) correctly deployed to the target environment and 2) correctly loaded at runtime.<br />
<br />
<a name='more'></a><br />
<b>Native binaries = Specific architecture (x86, x64, ...)</b><br />
<br />
Since native dependencies are built towards specific chipset architectures (x86, x64, ...) you need to include all versions in your distribution. Then at runtime you need to check which version to load. There already are some managed projects doing a good job on this, for example <a href="https://www.nuget.org/packages/System.Data.SQLite">SQLite</a>, <a href="https://www.nuget.org/packages/GDAL/">GDAL</a> or our own <a href="https://github.com/awesome-inc/VLC.Native">VLC.Native</a>.<br />
<br />
<b>Pick architecture at runtime</b><br />
<b><br /></b>The most simple solution is to just copy all native dlls right beside your executables directory. This way the AssemblyLoader will automatically pick up the native dlls (For more details see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx">this discussion on MSDN</a> on how Windows locate dlls).<br />
<br />
However, this only works if you are targeting the one specific architecture that the native binaries are built for. Otherwise you need to 1) distribute all native builds for x86, x64, ... and then 2) pickup the version macthing the archtecture at runtime.<br />
<br />
The most simple way to do this is to <a href="http://superuser.com/questions/392271/prepend-to-path-variable-windows">prepend the PATH environment variable</a>. For decades, software tools are deployed with 1) installers modyfying the PATH environment variable or 2) helper scripts starting a shell with modified PATH. Examples are <a href="http://www.gdal.org/">GDAL</a>, <a href="https://www.ruby-lang.org/de/">Ruby</a>, <a href="https://www.python.org/">Python</a> or <a href="http://git-scm.com/">Git</a> to just name a few.<br />
<br />
However, we neither want to persistently change the users enviroment possibly messing up some existing applications nor to have him execute a batch file everytime before using our software, right? Instead, we can change the PATH enviroment directly in our app right at startup in the so called <a href="http://blog.efvincent.com/di-bootstrap/">bootstrapping</a> phase.<br />
<br />
This i a nice way of picking up the right version that i saw first being used by the <a href="https://nuget.org/profiles/SharpMap-Team">SharpMap</a> team in their <a href="https://nuget.org/packages/GDAL/1.9.2">GDAL.Native</a> on NuGet gallery. Recently, we copied this pattern for our <a href="https://github.com/awesome-inc/VLC.Native">VLC.Native</a> package. We are deploying the native VLC dependencies to a common home directory with the x86 and x64 builds in subdirectories. Then at runtime, we check if we are running in 32 or 64 bits to the select the directory. Here is a snippet:<br />
<br />
<pre>void CheckVlc()
{
var vlcPath = Path.Combine(_homePath, "vlc");
var nativePath = Path.Combine(vlcPath, GetPlatform());
IsVlcPresent = Directory.Exists(nativePath);
if (!IsVlcPresent)
{
Trace.TraceWarning("Cannot find VLC directory.");
return;
}
// Prepend native path to environment path
var path = Environment.GetEnvironmentVariable("PATH");
path = string.Concat(nativePath, ";", path);
Environment.SetEnvironmentVariable("PATH", path);
//...
}
private static string GetPlatform()
{
return Environment.Is64BitProcess ? "x64" : "x86";
}
</pre>
<pre></pre>
<pre></pre>
<b><br /></b>
<b>Use </b><b>AppDomain.AppResolve with </b><b>mixed managed/native dependencies</b><br />
<br />
An more unusual case is depending on managed libraries that require separate builds for x86 and x64. If ever, you will find this mostly on commerical libraries porting some natives libraries to .NET using managed C++ or COM. Google for .NET libraries supporting RichText, PDF, Jpeg2000 or OCR features and you will probably find some examples. Generally, i would not recommend using such libraries, especially if they are commercial unless you have good reasons.<br />
<br />
Anyway, in case you are going down that road you need to extend the above bootstrapping code by hooking up into the <a href="https://msdn.microsoft.com/library/system.appdomain.assemblyresolve(v=vs.110).aspx">AppDomain.AppResolve</a> event and select the correct assembly like<br />
<br />
<pre> //...
Environment.SetEnvironmentVariable("PATH", path);
AppDomain.CurrentDomain.AssemblyResolve += ResolveCustomAssemblies;
}
private static Assembly ResolveCustomAssemblies(object sender,
ResolveEventArgs args)
{
var assemblyName = args.Name.Split(',')[0];
var assemblyFileName = Path.Combine(LookupPath, assemblyName + ".dll");
if (File.Exists(assemblyFileName))
{
var assembly = Assembly.LoadFrom(assemblyFileName);
Trace.TraceInformation("Resolved assembly \"{0}\" from \"{1}\"",
assemblyName, LookupPath);
return assembly;
}
return null;
}
</pre>
<br />
where <code>LookupPath</code> will usually be the path to the respective x86 or x64 subdirectory.<br />
<br />
<b>Minimize Footprint by factoring out native dependencies</b><br />
<b><br /></b>
So after all, distirbuting native binaries along with your app is fine unless you are deplyoing <a href="http://en.wikipedia.org/wiki/Smart_client">smart clients</a>, i.e. using <a href="http://en.wikipedia.org/wiki/ClickOnce">ClickOnce</a> or <a href="http://en.wikipedia.org/wiki/Java_Web_Start">Java WebStart</a>. The big advantage of smart clients is auto-updating so they make quick iterations easy but need small footprints to be practical. Since native dependencies tend to make your app a big download this is a killer for smart client deployment.<br />
<div>
<br /></div>
With smart clients like ClickOnce each update is a full, isolated, sandboxed copy of your app. This makes most deployment taks extremely simple, like auto-updating or rolling back to a specific version. As a consequence, you want to keep the size of your app as small as possible so updates will be quick and smooth.<br />
<br />
Fortunately, the native dependencies used in your app usually won't change much often, instead your app will, right? So what you can do is factoring out big constant binaries as a prerequisite. With ClickOnce, a <a href="http://msdn.microsoft.com/en-us/library/ms165429.aspx">bootstrapper package</a> is a reasonable choice. You can also go funky using a plugin-based approach like <a href="https://github.com/awesome-inc/NuPlug">NuPlug</a> which aims to download dependencies on demand.<br />
<br />
<div>
A typical use case might be a .NET client talking to an Oracle database backend so you need an Oracle Client like ODP.NET (which btw you can <a href="http://mkoertgen.blogspot.de/2012/05/xcopy-odpnet-with-oracle-spatial.html">squeeze down to about 35 MiB</a>). Assuming you already have ODP.NET as a prerequisite you can then take the following class</div>
<div>
<br />
<pre lang="csharp">class PathBootsTrapper : IBootsTrapper
{
private readonly string _path;
public PathBootsTrapper(string path)
{
if (String.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
if (!Directory.Exists(path))
throw new ArgumentException("Directory does not exist", "path");
_path = path;
}
public void Bootstrap()
{
var path = Environment.GetEnvironmentVariable("PATH");
path = String.Concat(_path, ";", path);
Environment.SetEnvironmentVariable("PATH", path);
}
}
internal interface IBootsTrapper
{
void Bootstrap();
}</pre>
<div>
<br /></div>
</div>
<div>
and use it like this:<br />
<br /></div>
<pre lang="csharp"></pre>
<pre lang="csharp">class Program
{
static void Main(string[] args)
{
var settings = new Settings();
pathToOracleClient = Environment.ExpandEnvironmentVariables(
settings.PathToOracleClient);
new PathBootsTrapper(pathToOracleClient).Bootstrap();
// ...
}
}</pre>
<br />
<b>Final words: Go for delta-updates with Squirrel</b><br />
<br />
Since there seems to be no active development on ClickOnce anymore you should look out for alternatives. Recently, Paul C. Betts et al. developed <a href="https://github.com/Squirrel/Squirrel.Windows">Squirrel.Wndows</a> which supports delta-updates and can be used to deploy non-.NET apps as well. However, at the time of writing, rolling back to a specific version is not supported, But why would you want to? A newer version should always be better, right? With <a href="https://github.com/mkoertgen/hello.squirrel">hello.squirrel</a>, i did a quick evaluation on Squirrel and really liked it.<br />
<div>
<br /></div>
<br />Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-39718435150184358092015-05-08T21:23:00.000+02:002015-05-09T11:13:55.986+02:00Yes, you can test it (1) - PrerequisitesBefore you start with unit testing, you must fulfill one prerequisites ... you need to create a unit. Sounds logic, but what does this mean?<br />
<br />
<a name='more'></a><br />
In OOP, all classes are connected to each other in some way. If there is a class without any coupling, it is either the god-object-all-in-one-main-class or you can delete it. You need to decouple these dependencies to make sure, another class does not have any unexpected effect on the class you want to test. Therefore you need to create an interface for each f***ing class, unless it is a pure data object (a DTO or POCO).<br />
<br />
This results in a lot of constructor and property injection with <i>interfaces </i>to be able to mock or fake these dependencies. A mock has exactly the behavior you define in your test. It does not have any side effects, or a dependent dependency which causes an unexpected behavior.<br />
<br />
<i>What do you need to do with your code?</i><br />
<i><br /></i>
Lets assume you have the following code:<br />
<blockquote class="tr_bq">
public class Foo<br />
{<br />
public void DoSomething()<br />
{<br />
// coupled to EmailSender<br />
var sender = new EmailSender();<br />
sender.Send("Whatever");<br />
}<br />
}</blockquote>
<div>
You have a dependency to EmailSender. To refactor the class without any breaking changes, you must ensure, the default behavior of class Foo still uses EmailSender, but you are able inject your own mock with an expected behavior. Thanks to C# 4 and default parameter, it is very simple: Use a constructor with a default parameter and extract an interface for EmailSender.</div>
<div>
<blockquote class="tr_bq">
public class TestableFoo<br />
{<br />
private readonly IEmailSender _sender;<br />
public TestableFoo(IEmailSender sender = null)<br />
{<br />
_sender = sender ?? new EmailSender();<br />
}<br />
public void DoSomething()<br />
{<br />
_sender.Send("Whatever");<br />
}<br />
}<br />
public interface IEmailSender<br />
{<br />
void Send(string message);<br />
}</blockquote>
</div>
<div>
This code does not produce any breaking changes, but you can mock IEmailSender and define a predictable behavior for Send().</div>
<div>
<br /></div>
<div>
This is the first step you need to do with a class you want test with unit tests. The great benefit is that you can do this on every brownfield project and refactor and test your code class by class.</div>
<div>
<br /></div>
<div style="text-align: right;">
<b>Think big, start small.</b></div>
Anonymoushttp://www.blogger.com/profile/03349722314831314332noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-70663367676723400462015-05-08T08:04:00.000+02:002015-05-09T11:14:46.473+02:00NEdifis: How we test if something got traced<div class="tr_bq">
Sometimes we have the requirement that something needs to be logged. Lets take some examples.</div>
<ul>
<li>a csv importer gets an invalid file. Although the app can handle it, a warning should be logged.</li>
<li>an exception got caught and is not re-thrown, an error should be logged.</li>
</ul>
<div>
We use a "log4net trace listener" to get our traces logged (which is another story) so tracing and logging is technically the same for us. </div>
<div>
<br /></div>
<a href="https://github.com/awesome-inc/NEdifis" target="_blank">NEdifis </a>provides an easy to use <a href="https://github.com/awesome-inc/NEdifis/blob/develop/NEdifis/Diagnostics/TestTraceListener.cs" target="_blank">trace listener</a> to receive all traces or logged messages. It uses the dispose pattern to register and deregister itself, therefore you need to dispose the TestTraceListener.<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; font-stretch: normal; line-height: 1.45; margin-bottom: 16px; overflow: auto; padding: 16px; word-wrap: normal;"><code style="background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; line-height: inherit; margin: 0px; max-width: initial; overflow: initial; padding: 0px; word-break: normal; word-wrap: normal;">using (var ttl = new TestTraceListener())
{
Trace.TraceError("here is a message");
ttl.MessagesFor(TraceLevel.Error).Should().Contain("here is a message");
}</code></pre>
Fortunately, debug uses the <a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.debug.listeners(v=vs.110).aspx" target="_blank">same listener collection </a>than tracing (but Debug has a System.Console like interface). So for debug, you can use the same trace listener and code.<br />
<br />
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; font-stretch: normal; line-height: 1.45; overflow: auto; padding: 16px; word-wrap: normal;"><code style="background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; line-height: inherit; margin: 0px; max-width: initial; overflow: initial; padding: 0px; word-break: normal; word-wrap: normal;">using (var ttl = new TestTraceListener())
{
Debug.WriteLine("nice debug");
ttl.MessagesFor(TraceLevel.Verbose).Should().Contain("nice debug");
}</code></pre>
<br />
Keep in mind that "System.Debug" only works if you app was compiled with "Debug". For "Release" this list is empty (<a href="https://github.com/awesome-inc/NEdifis/blob/develop/NEdifis/Diagnostics/TestTraceListener_Should.cs" target="_blank">see unit test</a>).<br />
<br />Anonymoushttp://www.blogger.com/profile/03349722314831314332noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-67857144012015574072015-05-06T23:09:00.000+02:002015-05-07T10:12:21.603+02:00NEdifis: How we organize our test classesFor the past decade I read a lot of articles about unit testing. There are thousands of best practices, do's, don'ts and especially workarounds. I remember a "trick" of a friend of mine who tried to find a way testing internal classes methods in a separate test project. His idea: he made these methods protected and created a derived class to wrap these methods in another internal method to access these methods from a test class. Yes, it is as complicated as it sounds.<br />
<br />
In our project we started to add our unit tests to the same project and kept them together. This gave us the ability to keep things internal which should stay internal. After some iterations we ended up with two conventions:<br />
<br />
<ul>
<li><b>Each test class ends with "_Should" so we can read tests easily</b></li>
<li><b>The test stays along with the class in the same namespace (folder)</b></li>
</ul>
<br />
The second point avoids the annoying duplication and maintenance of a folder structure or a huge namespace "Tests" with dozens of tests. In addition, you can see at a glance which classes don't have a test.<br />
<br />
For this cross-relation, <a href="https://github.com/awesome-inc/NEdifis" target="_blank">NEdifis </a>provides two attributes for this relation.<br />
<blockquote class="tr_bq">
<pre style="background-color: #f7f7f7; border-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; font-stretch: normal; line-height: 1.45; margin-bottom: 16px; overflow: auto; padding: 16px; word-wrap: normal;"><code style="background: transparent; border-radius: 3px; border: 0px; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.6000003814697px; line-height: inherit; margin: 0px; max-width: initial; overflow: initial; padding: 0px; word-break: normal; word-wrap: normal;">[TestedBy(typeof(TicketAttribute_Should))]
public class TicketAttribute : Attribute
{
}
[TestFixtureFor(typeof(TicketAttribute))]
// ReSharper disable once InconsistentNaming
public class TicketAttribute_Should
{
}</code></pre>
</blockquote>
This makes e.g. a navigation between these classes easier using "go to definition" and gives the opportunity for convention tests to check e.g. if each class has a test or a test fixture is properly named.<br />
<br />Anonymoushttp://www.blogger.com/profile/03349722314831314332noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-72476025471427084382015-05-06T07:15:00.000+02:002016-01-28T11:04:55.946+01:00How we organize branches and releases in GitHub<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0RyZXNTweKVe-938E2tYoqR_1Bv7Wzl9LaT6qUVbgK7GGRM5WKrDIeIU1dbWbYjMBb0NqsDJI_cGSIrLrYJQ5H2Kt3XZOUTSmlnqGVaGVc4GZ7WNdvOIu-UZtQDQ_9APrbWcPZTJBTio/s1600/gitflow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0RyZXNTweKVe-938E2tYoqR_1Bv7Wzl9LaT6qUVbgK7GGRM5WKrDIeIU1dbWbYjMBb0NqsDJI_cGSIrLrYJQ5H2Kt3XZOUTSmlnqGVaGVc4GZ7WNdvOIu-UZtQDQ_9APrbWcPZTJBTio/s320/gitflow.png" width="320" /></a></div>
<br />
After some experience with <a href="http://lucamezzalira.com/2014/03/10/git-flow-vs-github-flow/">Git Flow & GitHub Flow</a>, <a href="https://ci.appveyor.com/">AppVeyor</a> as Continous Integration tool, our <a href="https://github.com/awesome-inc/OneClickBuild">OneClickBuild</a> to simplify the build & deploy process and a bunch of other tools, we finally came up with the following workflow.<br />
<br />
AppVeyor automatically builds and tests the master branch and publishes the package to nuget. We need to increase the (semantic) version number <strike>manually in two files (<i>appveyor.yml</i> and <i>solution.targets</i>)</strike>, otherwise the publish step will fail. <br />
<br />
<ins datetime="2015-11-15T14:31:03Z">Note that we switched to <a href="https://github.com/GitTools/GitVersion">GitVersion</a> which automates versioning.</ins><br />
Therefore we don't want to get each typo, minor pull request or a change in a readme be reversioned and published to NuGet.<br />
<br />
So we created the develop branch as the default branch used for pull requests. If we decide to create a new version, we increase the version number and do a pull request to the master.
This reduces the number of NuGet versions but we still can manage as many pull requests as we want.<br />
<br />
Finally we use a simplified version of Git Flow but a more "complex" version of GitHub Flow. We don't create release branches in favour of pull requests. On the other hand we use a develop branch for pull requests.Anonymoushttp://www.blogger.com/profile/03349722314831314332noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-56675337699281426312015-05-05T17:02:00.003+02:002015-12-14T11:29:33.156+01:00GitHub: Boosting your README.md with status badges<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUN_45f7BKHc58Wb9CjdKi5ERy9XGWen69G84e9sUixB-UgckafSoHXdLYTotPog4s0vZnuP4YPylo2_PhbnxOJP-7Uw5Ao9z1HI8vWpQV-T3sMwtCyTBDE4Qk1TaXT3_eW-0ZBVhzjcw/s1600/good_to_go.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUN_45f7BKHc58Wb9CjdKi5ERy9XGWen69G84e9sUixB-UgckafSoHXdLYTotPog4s0vZnuP4YPylo2_PhbnxOJP-7Uw5Ao9z1HI8vWpQV-T3sMwtCyTBDE4Qk1TaXT3_eW-0ZBVhzjcw/s320/good_to_go.png" width="320" /></a></div>
<br />
One great thing about web-based repository hosting services like <a href="https://guides.github.com/features/mastering-markdown/">GitHub</a>, <a href="https://blog.bitbucket.org/2012/02/16/syntax-highlighting-for-markdown-readmes/">BitBucket</a> and others is their ability to directly render <a href="http://en.wikipedia.org/wiki/Markdown">Markdown</a> documentation as Html. Although typically used for static documentation you can easily enhance the web representation by referencing dynamic content by url.<br />
<br />
These days, a very common practice is to include status images, also known as <a href="http://en.wikipedia.org/wiki/Badge">badges</a>, at the top section of your <code>README.md</code> to indicate current quantities and metrics related to your repository, e.g.<br />
<ul>
<li>current build status (e.g. Jenkins, <a href="http://docs.travis-ci.com/user/status-images/">Travis CI</a>, <a href="http://www.appveyor.com/docs/status-badges">AppVeyor</a> and others),</li>
<li>package download count, total or per month (e.g. NuGet, npm, gem, etc...), </li>
<li>code quality stats like test coverage (e.g. <a href="https://www.codacy.com/">Coveralls</a>) or technical debt (e.g. with <a href="http://www.sonarsource.com/products/features/technical-debt-evaluation/">SonarQube</a>)</li>
<li>average time to close issues or accept pull requests (e.g. <a href="https://www.codacy.com/">Issue Stats</a> for GitHub)</li>
</ul>
<div>
This is a great and very simple way to improve the first impression of visitors and to show your professional working style.</div>
<div>
<br /></div>
<div>
How does it look? Head over to <a href="https://github.com/explore">GitHub</a> and explore some popular repositories. For example, i like <a href="https://github.com/Microsoft/TypeScript">Microsoft/TypeScript</a> or <a href="https://github.com/elastic/elasticsearch-net">elastic/elasticsearch-net</a>.</div>
<div>
<br /></div>
<div>
Here are some badges of our own projects</div>
<div>
<ul>
<li><a href="https://github.com/awesome-inc/OneClickBuild">OneClickBuild</a>: <img src="https://ci.appveyor.com/api/projects/status/qs1cu14tjvh1j0le?svg=true" /></li>
<li><a href="https://github.com/awesome-inc/NZazu">NZazu</a>: <img src="http://issuestats.com/github/awesome-inc/NZazu/badge/issue" /></li>
<li><a href="https://github.com/awesome-inc/NEdifis">NEdifis</a>: <img src="https://img.shields.io/nuget/dt/NZazu.svg?style=flat-square" /></li>
<li><a href="https://github.com/awesome-inc/FontAwesome.Sharp">FontAwesome.Sharp</a>: <img src="https://img.shields.io/nuget/v/FontAwesome.Sharp.svg?style=flat-square" /></li>
</ul>
</div>
<div>
<br /></div>
<div>
Popular badge providers seem to be <a href="http://shields.io/">shields.io</a>, <a href="http://badge.fury.io/">badge.fury.io</a> or <a href="http://issuestats.com/">issuestats.com</a>.</div>
<div>
<br /></div>
<div>
So, get badging!</div>
<div id="spoon-plugin-kncgbdglledmjmpnikebkagnchfdehbm-2" style="display: none;">
</div>
Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com0tag:blogger.com,1999:blog-4671721367922991683.post-68736900316693464962015-04-21T21:56:00.001+02:002015-04-21T21:56:07.864+02:00A quick and simple, throw-away NuGet serverWe are just beginning to work on a small open source lib for NuGet-powered plugin management called <a href="https://github.com/awesome-inc/NuPlug">NuPlug</a>. For testing purposes it would be nice to have a little, throw-away NuGet server. Since i am a big fan of <a href="https://www.vagrantup.com/">vagrant</a> and <a href="https://www.docker.com/">docker</a> i did a quick search on the docker ecosystem <a href="https://hub.docker.com/">dockerhub</a> finding <a href="https://registry.hub.docker.com/u/jonathanmorley/nuget/">jonathanmorley/nuget</a>. However, this is just an example of running the NuGet client within docker, not the server.<br />
<br />
For a NuGet server, you can simply <a href="https://docs.nuget.org/create/hosting-your-own-nuget-feeds">build your own</a>. But if you want it even simpler, you can use the <a href="http://blog.jonnyzzz.name/2012/03/nuget-server-in-pure-java.html">standalone-branch of TeamCity NuGet support</a>. I hacked together a few files that install and start the standalone NuGet feed on <a href="https://github.com/mkoertgen/hello.nuget.server">mkoertgen/hello.nuget.server</a><br />
<br />
Hopefully, someone will probably come up with a dockerfile that does just that.Marcel Körtgenhttp://www.blogger.com/profile/14923717275875440456noreply@blogger.com2