<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Trainline Team on Medium]]></title>
        <description><![CDATA[Stories by Trainline Team on Medium]]></description>
        <link>https://medium.com/@trainlineteam?source=rss-54ce459010e6------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*BoHC51j2kxV4hVXH-mzJNQ.png</url>
            <title>Stories by Trainline Team on Medium</title>
            <link>https://medium.com/@trainlineteam?source=rss-54ce459010e6------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 18:46:39 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@trainlineteam/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Trainline celebrates International Women in Engineering Day]]></title>
            <link>https://medium.com/trainline/trainline-celebrates-international-women-in-engineering-day-dbc585504e7e?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/dbc585504e7e</guid>
            <category><![CDATA[inwed17]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[women-in-tech]]></category>
            <category><![CDATA[engineering]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Fri, 23 Jun 2017 13:54:52 GMT</pubDate>
            <atom:updated>2018-03-08T11:32:07.651Z</atom:updated>
            <content:encoded><![CDATA[<p>It’s <a href="http://www.inwed.org.uk/">International Women in Engineering Day</a> (#INWED17) and although at Trainline we dig great engineering all year round, today we’re especially celebrating the diversity of our team and the successes of our brilliant women engineers. Better still, we’re sharing their stories to inspire more young women to investigate the amazing opportunities open to them in engineering and technology.</p><figure><img alt="Inwed collage" src="https://cdn-images-1.medium.com/max/800/0*7jNTJq1QEEbb9_xK.png" /></figure><p>Who better to tell their engineering stories than them? So…</p><h4>What does engineering mean to you?</h4><p>Engineering to me means building a solution to serve a purpose</p><p><strong>Jo Amarlapudi</strong>, Mobile QA Engineer</p><p>What I love in engineering is the intellectual challenge it poses to me and the opportunity to be creative and solve problems that can impact people in real life.</p><p><strong>Marta Ludovico</strong>, Agile Developer</p><p>Being empowered to help create something valuable every day</p><p><strong>Karen Parish</strong>, Agile Business Analyst</p><figure><img alt="karen live codes.jpg" src="https://cdn-images-1.medium.com/max/1024/0*wL8T8IaJa7CCVU6Z.jpg" /><figcaption>Karen Parish, Agile Business Analyst, discusses the importance of transparency in Engineering at Trainline Engineering Summit 17</figcaption></figure><p>Engineering = curiosity. It is the way you see the world. The need to figure out what’s hidden behind each and every object, how it works and noticing how awesome it is</p><p><strong>Aleksandra Koloczek</strong>, Platform Operations Engineer</p><p>Problem solving, building things our users love and learning new things every day</p><p><strong>Natalie Akam</strong>, Agile UI Developer</p><figure><img alt="natalie speaking.jpg" src="https://cdn-images-1.medium.com/max/899/0*_d210GIJ1UM_CzFl.jpg" /><figcaption>Natalie Akam, Agile UI Developer, speaking at Trainline’s Engineering Summit 17</figcaption></figure><p>Solving new challenges with creativity and passion…and working my butt off to understand my job!</p><p><strong>Xuan-Thi Nguyen</strong>, Software Engineer</p><p>Being an artisan or “craftwoman” of our times, as people in the iron age used to make beautiful and useful tools with iron, we now make beautiful and useful things with code.</p><p><strong>Teresa Jimenez Arreola</strong>, Agile Mobile Developer Android</p><p>What being an engineer means to me? It puts my creativity and imagination at the world’s service by evolving and improving people’s lives through technology</p><p><strong>Nisha Chaganlal</strong>, Agile Developer</p><figure><img alt="IMG_0026.JPG" src="https://cdn-images-1.medium.com/max/1024/0*-AS70mn0PP36mra_.jpg" /></figure><figure><img alt="IMG_0026.JPG" src="https://cdn-images-1.medium.com/max/1024/0*-AS70mn0PP36mra_.jpg" /><figcaption>Clare Gilmartin, CEO, speaks at NOAH Berlin 17 on technology in the travel industry and the importance of diversity at Trainline to create high-performing teams</figcaption></figure><p>To be an engineer is to join a culture dedicated to being open-minded, creative and wanting to continuously learn and adapt.</p><p><strong>Laura Willis</strong>, IT Support Engineer</p><p>To me, it’s looking for efficient solutions to any kind of problem you face in your day.</p><p><strong>Marion Mère</strong>, Software Engineer</p><p>Promote diversity, show that amazing things can happen when we are involved in this “majority male” domain.</p><p><strong>Audrey Sobgou</strong>, iOS Engineer</p><figure><img alt="women of trainline for silicon tech.png" src="https://cdn-images-1.medium.com/max/1024/0*8XoRPuQdbet-xaR_.png" /><figcaption>Some of our tech-loving women headed to Women of Silicon Roundabout earlier this year</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dbc585504e7e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/trainline-celebrates-international-women-in-engineering-day-dbc585504e7e">Trainline celebrates International Women in Engineering Day</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Build.Better Days]]></title>
            <link>https://medium.com/trainline/introducing-build-better-days-c1542d761614?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/c1542d761614</guid>
            <category><![CDATA[software-craftsmanship]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[culture]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Fri, 16 Jun 2017 12:56:21 GMT</pubDate>
            <atom:updated>2017-07-04T14:15:53.795Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/425/0*dK9XGGfMVnCqu_Kg.jpg" /></figure><p>We’ve been growing at an incredible rate here at Trainline. While it’s been amazing to see the constant stream of fresh, enthusiastic faces, it’s really put our engineering practices — and culture — through its paces.</p><p>However, <em>complete</em> autonomy that is easy to manage in small, nimble teams becomes unmanageable across hundreds of hard-working, creative engineers.</p><h4>Culture first</h4><p>Once you get past a certain organisational size (normally 50–150) — you really start to feel these “growing pains”, so it’s important to <strong>build</strong> a strong culture.</p><p>Notice the key word there — “build”.</p><p>It’s easy to <em>propose</em> a culture, socialising how you want people to “feel free” and “innovate”. But, when it comes down to sacrificing time, money, energy or “all of the above” to make it work — it starts to lose the fight and becomes nothing but a “good idea”.</p><p>Good culture is <em>hard</em>. Like anything worth having — it takes real commitment, energy and enthusiasm to make it work.</p><p>However, the payoff is worth it — you end up with an army of incredible people, who become far more than the sum of their parts. The organisation takes on a life of its own, life (and business) is good.</p><h4>Introducing “Build.Better Days”</h4><p>“Build.Better Days” (or BBD) are one of a series of initiatives that we’ve deployed to help us cultivate a great culture here at the big <a href="https://twitter.com/TrainlineTeam">@TrainlineTeam</a>.</p><p>Simply, <strong>these are a fortnightly “mini, internal hackathon”. They are a key component of — and our commitment to — “<em>aligned autonomy</em>”.</strong></p><h4>“Aligned autonomy”?</h4><p>If there was a bar where great engineering companies hang out — <a href="https://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/">Spotify</a> is certainly one Trainline would like to grab a beer with. We’ve been inspired by much of their work — especially the principle of “aligned autonomy”.</p><p>In a nutshell — it could be described as “<em>focused freedom</em>”.</p><p>It’s obvious that <em>complete</em> freedom (“yes, trains — <em>BUT</em> — we could build a robot to train my cat army because YOLO”) is damaging to a business/product roadmap — but less known is that it’s equally damaging <em>psychologically</em>. Often, those that can really do <em>anything</em> end up feeling lost and do <em>nothing</em>.</p><p><strong>“Aligned autonomy” is about putting a <em>few</em> constraints and a dash of vision to the freedom to help give people a sense of direction.</strong></p><p>Let’s get down to how Build.Better Days work.</p><h4>Freedom first</h4><p>First and foremost — you’ve got to give the <em>freedom</em>. We’ve got a company-wide, fortnightly meeting in the calendar on Friday that says “Build.Better Day”. That means:</p><ul><li>Engineers have the time/space to get away from “day to day” development and focus.</li><li>Engineering teams may not be available or at 100% capacity.</li><li>There’s going to be a lot of hackers in our “collaboration space” (an open, flexible area of our office).</li><li>There’s going some stuff to go “oh that’s cool” at by the end of the day.</li></ul><p>BBD is about giving people the time and space to innovate, while surrounding them with people with the talent to <em>get it done</em>.</p><h4>Everyone has a voice</h4><p>On our internal Wiki — there’s a button that everyone has access to. Clicking this button will open a JIRA “issue collector” that take whatever they put and place it into our BBD backlog for triage.</p><p>Everyone can raise ideas, from any team, no questions asked.</p><h4>Triage of BBD backlog</h4><p>Every <em>week</em> all of those that have items “to triage” in the BBD backlog get together with a few of the senior/principal engineers to review.</p><p>The goal of this session is to really “groom” the items in triage to help make the actual <em>day</em> productive — so we help each other:</p><ul><li>Build a great user story around the idea.</li><li>Help with scoping to ensure it’s going to deliver <em>something</em> at the end of the day.</li><li>Make sure we’re “aligned” — proposed technologies are core to our stack, contribute to our company vision etc.</li><li>We’re not building robot drill instructors to train cat armies.</li></ul><p>We’ll also review items that are “in progress” and clarify “what’s next” to help them move closer to completion.</p><h4>Pre-day preparation</h4><p>With a relatively large number of hackers descending on a single space — it’s important to have a basic pre-flight checklist to ensure things are in order:</p><ul><li>Food requirements (did I mention we order food?)</li><li>Work space is free, no clashes of meetings.</li><li>Do we have enough power extension cables, display adapters etc?</li><li>Usual consumables — whiteboards, pens, post-its, etc.</li></ul><h4>On the day</h4><p>We keep the format of the day loose:</p><ul><li>09:30 — People gather in the workspace, caffeinate and converse.</li><li>10:00 — Recap of “the rules” and pitches from idea creators.</li><li>10:30 — Hacking — teams self-organise.</li><li>13:00 — Lunch.</li><li>13:30 — More hacking!</li><li>16:30 — “Show and tell” to the rest of the business.</li><li>17:00 — Laptops closed, beers open.</li></ul><h4>The “rules”</h4><p>We try very, very hard to keep this list short.</p><ol><li><strong>Only work on “triaged” items</strong> — this ensures that people are only picking up things that are well-defined and “actionable”. A whole day is short than it sounds!</li><li><strong>Every team does a “show and tell”</strong> — it’s important that we demonstrate progress to each other. We might get working code, or “we tried, couldn’t get it to work, but learned <em>X</em> for next time”. Both are “success”.</li><li><strong>Stay in the BBD space</strong> — this is to reduce disruptions for all concerned. It’s easy for non-participants to ask “what are you working on”. Repeated 2–3 times and you’ve lost over an hour of focused development time.</li><li><strong>Have fun</strong> — it’s still a hackathon. 😊 Progress over stress.</li></ol><h4>Outcomes</h4><p>We’ve had 5 BBD’s so far, and we’ve seen a wide range of awesome output — including:</p><ul><li><em>Incredible</em> development/improvement of our build/deployment pipelines.</li><li>Slack bots to help people find their way around the office.</li><li>Libraries to help engineers “do the right thing” easily — e.g. the <a href="https://martinfowler.com/bliki/CircuitBreaker.html">“circuit breaker” pattern</a>.</li><li>Clean-up of legacy code/libraries to both boost performance of our applications and maintain sanity of engineers.</li><li>Better integration of our deployment pipelines to APM tools such as New Relic.</li></ul><p>For me personally, I think the greatest outcome so far is:</p><p><strong>People “get it”. They are getting involved and improving things for each other.</strong></p><h4>To close…</h4><p>I’m really enjoying seeing Build.Better Days grow and evolve.</p><p>It’s (unfortunately) rare to see real commitment to initiatives such as these in our industry (even the famous <a href="https://qz.com/117164/20-time-is-officially-alive-and-well-says-google/">“20% time” from Google is struggling</a>). BBD has <em>full</em> support from the leadership team, and we work hard to keep the “rules” and bureaucracy minimal.</p><p>So, <strong>will <em>you</em> take the plunge and give your team the time, space and energy to Build.Better?</strong></p><p>Happy hacking!</p><h4>Links</h4><ul><li>“Spotify Engineering Culture — <a href="https://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/">Part 1</a> and <a href="https://labs.spotify.com/2014/09/20/spotify-engineering-culture-part-2/">Part 2</a>” — mandatory viewing for new Trainliners.</li><li>“<a href="https://www.slideshare.net/jchyip/enabling-autonomy-at-spotify">Enabling Autonomy at Spotify</a>” — great talk from Jason Yip (<a href="https://twitter.com/jchyip">@jchyip</a>) at Spotify.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c1542d761614" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/introducing-build-better-days-c1542d761614">Introducing Build.Better Days</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Practicing Evolutionary Management at Trainline: Experiments in Self-Management and Wholeness]]></title>
            <link>https://medium.com/@trainlineteam/practicing-evolutionary-management-at-trainline-experiments-in-self-management-and-wholeness-650b0d997168?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/650b0d997168</guid>
            <category><![CDATA[product]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[evolutionary-management]]></category>
            <category><![CDATA[psychology]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Wed, 26 Apr 2017 09:56:27 GMT</pubDate>
            <atom:updated>2017-07-04T14:20:57.709Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bUD8j6DW9R0mALNPiHlRwA.png" /></figure><p><a href="http://engineering.thetrainline.com/2017/03/02/practicing-evolutionary-management-at-trainline-the-journey-to-evolutionary-teal-and-beyond/">Part one of this series</a> describes my journey towards discovering this way of working and the foundations of evolutionary management. Here in part two, I detail what we learned from experiments designed to create breakthroughs in self-management and wholeness — the good, the bad, and the beautiful.</p><h4>Self-Management Practices</h4><h4>The Advice Process</h4><h4>Experiment:</h4><p>When our team was still small (&lt;20), we agreed a new decision-making policy called the advice process. The advice process is simple — <em>any person can make any decision after seeking advice from 1) everyone who will be meaningfully affected, and 2) people with expertise in the matter</em>. This means that every decision has a responsible owner accountable to the group, but this person can be anyone within the team — not just those at the top of a pyramid.</p><h4>Results:</h4><p>Our team agreed to this policy because, as one developer put it, “it makes everyone empowered,” and indeed it seemed to boost engagement. However, we learned it was insufficient to ensure code quality and consistency, as our team members had differing understandings with our tech stack and standards. Particularly as the team grew, we realised that we needed someone in charge — but not an autocratic team lead. We simply had to define more stable decision-making accountabilities, particularly over code quality, without diminishing the power of team members. We found a solution in what I call <em>the three-layer cake of accountabilities</em>.</p><h4>The Three-Layer Cake of Accountabilities</h4><h4>Experiment:</h4><p>When the team grew past 25 (and eventually to over 50) people, we broke it down into five squads, each owning a different area of the application. The tech leads along with each squad’s developer in test ensured quality through the stack. To ensure consistency across the stack, we created a parallel guild structure with guild leads, inspired by <a href="http://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/">Spotify’s org structure</a>. However, we went beyond the Spotify template and defined a third set of roles, which we called the <em>Champions of Excellence.</em> The Champion of Excellence role evangelises for a particular aspect of product quality we care about, learning about and educating other team members on subjects like accessibility, performance, and security. While myself and our development manager suggested these roles, the team expanded and filled them voluntarily.</p><h4>Results:</h4><p>These new accountabilities remain in place, and the team is rolling. Code quality is high thanks to leadership from the squad leads and guild leads, but vesting more power in these roles has not disempowered others <em>because there remain other accountabilities with power</em>. Indeed, the great majority of team members now have meaningful opportunities for leadership and accountability beyond their day to day functional specialties. More importantly, the three-layer cake management structure was agreed and implemented by the team and therefore reflects our best efforts to self-organise around the challenges we face.</p><h4>Wholeness Practices</h4><h4>Check-ins</h4><h4>Experiment:</h4><p>We began by starting team ceremonies with a minute of silence as detailed in <a href="http://www.linkedin.com/pulse/practicing-evolutionary-management-trainline-part-one-ian-randolph">part one of this series</a>. We then naturally moved to a verbal check-in practice whereby we’d go around the room, each team member sharing how they were feeling at that moment in a few words. This practice took about a minute and rarely finished without a round of knowing laughter. Each said what was really there for them, whether that was being excited for the week or hungover from last night.</p><h4>Results:</h4><p>Both these practices had the same effect — everyone got present. Laptops shut, eyes came up, and the group became intensely focused on the conversation. Our meetings became not only more efficient but also more enjoyable. We ended up sticking with verbal check ins longer. By speaking a small emotional truth, we were licensed to speak larger truths and get to the heart of the matter. And in doing so, we could simply be ourselves.</p><h4>Words of Gratitude, Praise, and Acknowledgment</h4><h4>Experiment:</h4><p>It is traditional in Scrum to have a demo day at the end of the sprint where the team shares their accomplishments. We certainly didn’t skip this. Indeed, we had somewhat decadent weekly wrap-ups with tons of sweets and snacks to celebrate. Adding to that tradition, we set aside time to honour not just works of achievement but also acts of cooperation. After demos were done, I asked the team a question — “Who would like to share words of gratitude, praise, or acknowledgment with your colleagues?” Team members then spontaneously addressed one another.</p><h4>Results:</h4><p>I always looked forward to asking this question. Team members have acknowledged each other for providing training, for responding quickly to crises, and for simply being there for each other on tough days. It is in these conversations in which the team has created who we are through our expectations for one another — we <em>are</em> generous, we <em>are</em> resilient, we <em>are</em> compassionate. I’ve found the practice remarkably powerful.</p><h4>Performance Evaluations from Wholeness</h4><h4>Experiment:</h4><p>Performance evaluations in the <em>Achievement-Orange</em> paradigm can be dispiriting conversations. While intended to be objective and dispassionate, they’re in reality often tinged with fear and anxiety.</p><p>I tried something different with one of my direct reports, Janie (not her real name). I gathered Janie and her closest colleagues in a well-lit meeting room, arranging the group in a rough semicircle around her. We began with a minute of silence, during which I asked the group to hold Janie in their hearts. Then, one by one, each of Janie’s colleagues offered her two gifts from a place of love and connection. These two gifts were the answers to the questions, <em>What is the one thing I value most about working with you?</em> and <em>What is one area where I sense you could change or grow?</em> While they spoke, I transcribed the answers on a whiteboard behind Janie, and I gave a photo of these answers to her after everyone had spoken. I then followed up with Janie to discuss what she discovered about herself and how she sensed she wanted to grow next.</p><h4>Results:</h4><p>There was an incredible love and generosity in the room throughout this process. Were it not for British norms against expressing emotion in the workplace, I felt there might have been tears. The results were not only moving but also useful. Valued traits were deep acknowledgments of strengths, some of which Janie had not fully appreciated, while suggestions for growth got right to the root her challenges. Those who participated from different teams requested that they receive such an evaluation, saying how it wasn’t fair that their teams didn’t do the same.</p><h4>Handovers from Wholeness</h4><h4>Experiment:</h4><p>I adapted the above format to bring wholeness to handing over my role as product owner for the web team. After 15 months of product leadership, I chose to hand over this role and pick up a new one as product owner for the data science team. I wanted to set up my successor for success, but I also wanted to acknowledge and celebrate what I brought to the team so that I could fully let go. When it came time to hand over accountability to my successor (who was Janie, in fact) for the mobile web squad, I gathered the group together in a semicircle around the two of us. After a minute of silence, each team member shared the answers to the questions, <em>What is the one thing I valued most about working with you, Ian?</em> and <em>What is one wish I have for Janie for the future?</em></p><h4>Results:</h4><p>The team showed up as generous and authentic, sharing moving words for both of us about what they loved and what they hoped for. I felt complete and ready to move on, while Janie said she felt a new relationship with the team starting to grow. I look forward to trying this again for my next role transition.</p><p>In part three (coming soon), discover what we learned from experimenting with practices designed to evoke evolutionary purpose, including what I consider the most powerful evolutionary management practice.</p><h4>About the author</h4><p>Ian is a senior product owner at Trainline passionate about building great products, teams, and organisations. Born and raised in the San Francisco Bay Area, he has been working and learning proper English in London for the past six years. Ian has an MSc in Decision Sciences from the London School of Economics and a BA in Cognitive Science from Yale University.</p><p><a href="http://engineering.thetrainline.com/2017/03/02/practicing-evolutionary-management-at-trainline-the-journey-to-evolutionary-teal-and-beyond/">&lt;&lt; Part 1: Practicing Evolutionary Management at Trainline: The Journey to Evolutionary-Teal and Beyond…</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=650b0d997168" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring-clean your backlog]]></title>
            <link>https://medium.com/trainline/spring-clean-your-backlog-f83f92862037?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/f83f92862037</guid>
            <category><![CDATA[product]]></category>
            <category><![CDATA[agile]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Fri, 07 Apr 2017 09:28:58 GMT</pubDate>
            <atom:updated>2017-07-04T09:48:03.363Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="119_3872x2592_all-free-download.com_20539280" src="https://cdn-images-1.medium.com/max/1024/0*jOMFC8w6MNwTSEQK.jpg" /></figure><p>Is your development backlog too big? Do you to find yourself having two backlogs without realising it? One which is high priority items, recent defects and tasks to be completed in the next few weeks, and one which is full of nice-to-haves, low priority defects and legacy requests? I think we all know what gets the focus and what is just muddying the waters.</p><p>This is a common problem I’ve found with pretty much every project I’ve ever worked on, and I’ve found a few steps that have really helped to get your backlog looking in a much healthier and more manageable state.</p><p>You can only focus on so much at once, and not being able to see the wood for the trees, as it were, can cause a team to lose focus. We can only take in so much information at once, and there’s no way a Product Owner can efficiently prioritise a hundred items or more.</p><h4>Out with the old</h4><p>A good rule of thumb, is that if something is over a year old, and hasn’t been done, then GET RID OF IT.</p><p><strong>If it’s a product request:</strong> it obviously isn’t important enough to have been prioritised up to now, and therefore it is pretty unlikely that it will get done in the next year. Unless your business stagnates and you are struggling to find things to do, in which case, you’ve probably got bigger problems.</p><p><strong>If it’s a defect:</strong> it was that much of an issue, it would have been fixed. And if something changes which causes this defect to crop up again (perhaps more severely) then a new ticket can be raised, probably with much more relevant and accurate information than a year ago.</p><p>If you’ve ever moved house and had a massive clear-out of things you don’t need, hopefully you can relate to the following question:</p><h4>How many times have you missed the items that were gone?</h4><p>It’s normally pretty rare that you will, as if you haven’t used something in 5 years, you are unlikely to need it again in the next year or two. The same is true of development, especially as you are theoretically buying new products on a daily basis! Once you’ve done this initial clear out, you’ll find it a lot easier to do the next step.</p><h4>Looking too far forward</h4><p>Again, if there are stories/requests in there for functionality which is not in line with the business priorities for the next 6 months or year, then there is probably no need to have it in your backlog. In a tech company, it is very difficult to predict what the future will be like, and there is no point trying to work out the details of these stories now or wasting your time on something which may never happen. So if you honestly can’t see it getting done within the next year, GET RID OF IT! This will allow you to focus on the main business priorities. These things should be kept elsewhere, as part of a Product Owner roadmap or at an epic level with no stories.</p><h4>Timeboxed small defect clear out</h4><p>There always seem to be these little requests/tasks/defects which are very small changes, and they need to be done. At some point. The issue with these is that they are generally not the most exciting things to work on, and are likely to be the last thing someone will pick up, especially when there is something much more appetising on the backlog. I’ve found that a great way to tackle these is to have a timeboxed “Defect Attack Week”. Although this doesn’t have to be a week, maybe it could just be two or three days:</p><ul><li>Decide on the top 5–10 bugs that have been lingering (or more if you’re feeling ambitious)</li><li>Write each on a post-it and place on the wall near the team</li><li>Every time someone fixes one, move the post-it, throw it away/up in the air in celebration</li><li>See how many you can fix in the timebox and if the team clears them all, have some treats to recognise it</li></ul><p>This approach can also work leading up to a big release or project closure when you’re discovering lots of defects.</p><p>Once your backlog is relevant, minimalist and focused, you’ll hopefully find planning and prioritising much easier.</p><h4><strong>Happy Spring Cleaning!</strong></h4><figure><img alt="bunny" src="https://cdn-images-1.medium.com/max/1024/0*thhkOFC5DFMt1Jub.jpeg" /></figure><h4>About the Author</h4><p>Karen is a Business Analyst at Trainline. She has a passion for agile development, continuous improvement, and eating and drinking her way around London (Instagramming wherever possible!)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f83f92862037" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/spring-clean-your-backlog-f83f92862037">Spring-clean your backlog</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[UI Automation for the Trainline iOS App: Tooling and Performance]]></title>
            <link>https://medium.com/trainline/ui-automation-for-the-trainline-ios-app-tooling-and-performance-d1bc035ac14b?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/d1bc035ac14b</guid>
            <category><![CDATA[software-testing]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[quality-assurance]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Thu, 23 Mar 2017 10:07:28 GMT</pubDate>
            <atom:updated>2017-07-04T14:28:48.076Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/852/0*mD7SpwJ2wtS2OFMx.jpg" /></figure><p>In my previous <a href="https://engineering.thetrainline.com/2016/12/09/stubbing-for-ui-automation-in-ios">post</a> I discussed some questions around UI automation testing for iOS applications. I looked into questions regarding stability and the use of stubbing data as a base for most UI tests.</p><h4>Choosing the right tools</h4><p>The most important part of doing automation is to choose the right tools. There is plenty of choice on the market for UI automation testing tools for iOS. Appium, Calabash, KIF — these are just some of the big players you can choose from, not to mention a large number of smaller ones and one native tool — Apple UI Automation. All of these tools have some benefits but also some disadvantages.</p><p>The main challenge is this: <strong>there is no ideal solution</strong>.</p><p>Below, I will share with you my thoughts and conclusions about some of them — and I really hope this will help you choose the most appropriate tool for your team when the time comes. To keep these learnings manageable, I will focus on some key, well-known tools as well as the native Apple solution — not, for obvious reasons, the Apple legacy JavaScript implementation, but rather the modern Xcode UI Tests framework based on Swift (you guys know what I’m talking about, right?).</p><p>Also, I really must emphasise that all of the points and thoughts below are based on empirical evidence: we have actually used all of these solutions at Trainline at various times. All of this is real experience and learning.</p><h4>Appium</h4><p>This is a really good tool that has a lot of benefits and good thinking behind it. It’s open-source, free to use and quite easy to setup. A huge benefit of this tool is its cross-platform nature. So, if you have iOS and Android apps, with similar features and UI, and you want to use one tool to write automation for both of the apps, then Appium could be for you.</p><p>Here are some of the other <strong>benefits</strong>:</p><ul><li>tagging for tests scenarios</li><li>abstraction level for Scenarios using Gurkin</li><li>quite easy to setup</li><li>cross-platform</li><li>black-box approach, completely external to project.</li></ul><p>Here are couple of issues which we found to be <strong>drawbacks</strong>:</p><ul><li>very slow after the latest iOS release.</li><li>Java based — so it’s not native for iOS developers</li></ul><h4>Calabash</h4><p>Here are some plus points:</p><ul><li>tagging for tests scenarios</li><li>abstraction level for Scenarios using Gurkin</li><li>easy to setup</li><li>have cross platform capability</li><li>able to run tests on Real devices</li><li>relatively fast for tests run</li></ul><p>But here are some unfortunate minuses:</p><ul><li>requires recompiling the project specifically for tests to run</li><li>invasive as it requires the injection of the Cucumber library with HTTP Server in order to implement communication with the Ruby part</li><li>Ruby-based — so, again, it’s not native for iOS developers</li></ul><h4>KIF</h4><p>This is quite an old tool which is, by nature, much closer to Xcode UI Tests rather then to the Appium or Calabash approach.</p><p><strong>Pros</strong>:</p><ul><li>very close to development, as it uses Objective-C as the main language</li><li>fast to run</li><li>easy to setup</li></ul><p><strong>Cons</strong>:</p><ul><li>very invasive as it literally runs inside your app</li><li>no cross-platform capabilities</li></ul><p>Also I need to mention that this tool uses UnityTests style, more commonly known as JUnit test style, for writing tests. This could be a pro or a con depending on your point of view.</p><h4>Xcode UI Tests</h4><p>This is the native solution from <em>Apple</em>. More precisely, the <em>second generation</em> native solution. The first implementation from <em>Apple</em> was based on JavaScript and didn’t integrate properly with the <em>IDE. Instead,</em> you had to use the <em>Instruments</em> application to access those scripts without any syntax highlighting or auto-completion. So it was a really messy, unstable and unmanageable way of writing UI automation for iOS.</p><p>Xcode UI Tests, on other hand, is quite a mature and thought-through tool. With some references to the past JavaScript UI automation in its structures, you can use, or access, elements and search controls, but they have been rewritten in Swift and propositioned by <em>Apple</em> as the main tool for UI automation on iOS.</p><p>Like the previous tool, Xcode UI Tests uses JUnit style for test writing and works as set of unit tests by adding a new bundle to your project, and it integrates perfectly with <em>Xcode</em> and <em>Xcode Bots</em>.</p><p><strong>Pros</strong>:</p><ul><li>fast — it’s actually really fast.</li><li>no need to integrate anything or do any additional setup — works out of the box</li><li>uses Swift as its base language - perfect for native developers.</li><li>great integration with Xcode from writing tests to getting feedback from test runs.</li><li>black-box testing, as test runs on top of a sand-boxed app instance</li><li>stability: from my experience tests run more stably and more predictably in comparison with other tools.</li></ul><p><strong>Cons</strong>:</p><ul><li>no tagging, harder implementation for CI to run a specific subset of tests.</li><li>no cross-platform capabilities</li></ul><h4>Requirements and choice problem</h4><p>So, once we had evaluated all the available tools and listed the key pros and cons, in order to actually choose the right tool, we really needed to think about <em>our</em> specific requirements: what were the significant factors which would impact most on us? This is what we identified:</p><ol><li><strong>A team approach:</strong> We wanted to have developers closer to UI automation. As I mentioned in my <a href="https://engineering.thetrainline.com/2016/12/09/stubbing-for-ui-automation-in-ios">previous article</a> — UI automation is a team effort, all team members should contribute to it.</li><li><strong>Performance:</strong> We needed something fast, in order to connect test runs into the continuous delivery pipeline. This is very important for the overall quality of the product. If you have your test runs before you ship anything to customers, you significantly reduce the risk of shipping something bad.</li><li><strong>Stability:</strong> We needed something reliable, something that would not fall apart with the next iOS release or stop working if <em>Xcode</em> were to update to new version.</li><li><strong>Smooth integration:</strong> We needed something that integrates natively and smoothly into the development environment with the minimum of setup and overhead.</li></ol><p>We decided not to restrict ourselves to a cross-platform solution, but rather, take something really optimal and specific for <em>iOS</em> and make the best out of it.</p><p>Taking all of this into account, it was quite obvious that Xcode UI Tests — was the one and that we should try to incorporate it in our development practices more heavily. It is based on a native for the team language — Swift, allowing a black-box testing approach to a sandboxed app with the minimum of impact on our main app code. It’s the fastest available tool on a market that integrates natively with no context switching for developers. It uses the same tools we use day-to-day: - <em>Xcode</em>, showing you the output of your tests in the same <em>IDE</em> you use for coding and in the same style with which we were already familiar from unit tests.</p><p>Although it doesn’t have a tagging system or natural language support for writing tests scenarios, it is still the best available tool that the team can use. And, as you will see below, those disadvantages could be mitigated with the use of certain techniques.</p><h4>Performance boosting tips</h4><p>OK, so we chose Xcode UI Tests. Now for some more details around how it’s all set up here at Trainline.</p><p>The basics, such as <em>Xcode</em> setup or adding UI Test targets to the application, can be found in the <a href="https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/09-ui_testing.html#//apple_ref/doc/uid/TP40014132-CH13-SW1">Apple documentation</a>, and there is also a handful of tutorials online. So this post will instead focus on some aspects related to the performance of the tests.</p><p>Here are some tips, based on the experiences of our team, for using Xcode UI Automation on a real app over some period of time, which will help to speed tests up and improve the stability of test runs:</p><ul><li>log out any active users between test runs and clear data. This makes all tests run independently on a fresh setup of the application, so you eliminate any possibility of failures caused by some garbage being left over by a prior test</li><li>use stubbing data for most of the tests. This will allow you to minimise any slowness with real service latency of responses and potential variations in responses</li><li>write tests “wisely”, meaning that it may be prudent to combine a few scenarios in one in order to reduce the amount of runs with the same coverage</li><li>do not over-complicate your tests. Tests should be quite deterministic and not do too much. You really need to find some middle ground on what tests should look like</li><li>split tests into groups. This will allow you to do more careful selections if needed on <em>CI</em> to run a group of tests in a specific area, such as a payment system, for example — it should just be a matter of pointing your CI to specific folder</li><li>select some sanity tests to run on each commit on CI. Do not try to run everything every time as it will take a long time and not really bring a lot of value</li><li>use expectations to make sure you are interacting with elements that exist - this will minimise occurrences of false failures of tests</li></ul><p>Another trick worth considering is to disable any animations within the app. You will be surprised how much time you gain by doing this! The downside of this, of course, is that there becomes a point when you can argue that this is not really running the real app and you will be testing modified code and I would agree with this. However, generally speaking, this is not as bad as it may sound, as we are only disabling UIView animations and so no functionality is being changed. So if you are ready to compromise a little bit on that in order to gain a performance boost for your tests, this is a neat trick!</p><h4>CI integration</h4><p>Another important question is how to integrate tests into the delivery pipeline. If a test suite is not integrated and, instead, left on a manual execution cycle, it gets forgotten and starts to rust, so they end up being a complete waste of effort and time. So in order to really benefit from UI automation tests, they have to be included in the continuous delivery pipeline and in the development process overall. And really importantly to understand why we do that, the main reason being to minimise the possibility of delivering a broken product. Making sure that automated tests are running constantly on any change we do should guarantee better stability and minimise any possibility of some simple, but costly, error slipping through. Also UI automation is the perfect tool to offload manual testing overhead to free up some valuable QA time to do exploratory testing.</p><p>Taking into account all of the above, we began with a simple setup of running all tests we have on anything we were about to merge to the development branch. This proved to be a good step to start from: while there were not many tests to start with, it made sense to have them all running often, so we could see how stable they were and what performance was like. We agreed that to get anything merged into the development branch, it should have UnitTests and UI Automation passed.</p><p>But with your test suite growing, it is inevitable that it will at some point take too long to run all of the tests every time. And this is where the idea of splitting the tests into multiple suites came to the fore.</p><p>Ideally you want to have a selective run when working on a feature or are fixing some issue and you just need to make sure that the area you are affecting is not broken, or that the feature you are implementing works as expected. But as you will see, there are certain limitations and problems around this. So for some time we decided to implement a simple solution of having two tests bundles: one with some sanity tests to cover most of the app functionality in a few tests on the most important key areas; and the second — all of the tests. With this, we can run a small subset of tests on every commit and before merging to development, and a large set of tests to run over night on the main development branch to check if all the work done during the day is still stable.</p><p>Although the Xcode UI Tests tool does not have a tagging system to define a group of tests, unlike Calabash, for instance, we still have few options to implement such functionality.</p><h4>Using Schemes</h4><p>The simplest way is to set up different <em>schemes</em> inside your pr<em>oject</em>. Basically, for a specific s<em>cheme</em> you can choose what to run, specify tests, bundle of the tests or suite to run on <em>CI</em>. And this is quite simple to do, you do not need to duplicate code or targets.</p><p>You just need to add new s<em>cheme </em>in the “<em>Manage schemes…”</em> menu or duplicate existing one with tests. And you will be able to specify what tests to run when this s<em>cheme</em> is selected. It should be dead simple to configure <em>CI</em> job to run this custom <em>scheme</em>. And you will have just subset of tests that got run there with results for them.</p><p>This setup lead to one complication though — this is all manual process, and in case you need to change anything when number of tests grown up significant, it will be really easy to lose context there. So maintainability cost will be quite significant with such approach.</p><h4>Using the command line</h4><p>Luckily, <em>Apple</em> introduced a different way of doing that with the new <em>Xcode 8</em> on the last <em>WWDC</em>. It’s a slightly more complex way that requires some more setup on <em>CI</em> and some work with scripts, but it gives a more automatic and flexible way of doing that.</p><p>I’m talking about two new console commands that allow us to split builds from the test run.</p><p>One is build-for-testing which allows us to do only a build of a project and produce some resources that could be shared across a few build agents to run tests.</p><pre>xcodebuild build-for-testing -workspace <br>                 -scheme <br>                 -destination</pre><p>And another one: test-without-building. This command allows you to only run the test if the application was already built with the previous command and we have the generated resources.</p><pre>xcodebuild test-without-building -workspace <br>                 -scheme <br>                 -destination</pre><p>Also, there is one more new addition to the family of commands for console runs of the tests or, rather, an addition to the normal xcodebuild one.</p><pre>xcodebuild test -workspace <br>        -scheme <br>        -destination <br>        -only-testing:TestBundleA/TestSuiteA/TestCaseA<br>        -only-testing:TestBundleB/TestSuiteB<br>        -only-testing:TestBundleC<br>        -skip-testing:TestBundleD/TestSuiteD/TestCaseD</pre><p>So, by using -only-testing and -skip-testing we are able to set up more flexible and targeted ways of running a subset of tests on <em>CI</em> and it could be done per feature, or just to achieve some parallelisation for running tests which will become quite important, at some stage, as the test bundle grows and thus the time it takes to run all the tests becomes bigger.</p><h4>Summary</h4><p>In conclusion, I would like to say that, at Trainline, we as a team went on quite a long journey trying different variations of tools and setups before ending up with Xcode UI Tests. In short, our journey looked like this:</p><p>KIF -&gt; Calabash -&gt; Appium -&gt; Calabash -&gt; Xcode UI Tests</p><p>Yes, we even tried to implement Calabash more than once. The second attempt was more successful and we used it for some time. What we learned here is to continue searching and trying. It’s impossible to achieve something without trying. We failed a few times, but we kept looking and trying and now we have a highly maintainable, stable, performing solution for our <em>UI automation</em> requirements which we keep improving.</p><p><a href="http://engineering.thetrainline.com/2016/12/09/stubbing-for-ui-automation-in-ios/">&lt;&lt; Previous: Stubbing for UI Automation on the Trainline App</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d1bc035ac14b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/ui-automation-for-the-trainline-ios-app-tooling-and-performance-d1bc035ac14b">UI Automation for the Trainline iOS App: Tooling and Performance</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Practicing Evolutionary Management at Trainline: The Journey to Evolutionary-Teal and Beyond…]]></title>
            <link>https://medium.com/trainline/practicing-evolutionary-management-at-trainline-the-journey-to-evolutionary-teal-and-beyond-a76e793360ce?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/a76e793360ce</guid>
            <category><![CDATA[product]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[evolutionary-management]]></category>
            <category><![CDATA[psychology]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Thu, 02 Mar 2017 09:41:13 GMT</pubDate>
            <atom:updated>2017-07-04T14:29:59.837Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*bUD8j6DW9R0mALNPiHlRwA.png" /></figure><p>The gong went off with a humming twang.</p><p>Around the table, 20 people sat staring. Our agile web team had kicked off many sprint planning meetings, but none like this. As the sound of the Tibetan meditation bowl receded into silence, nervous impulse rushed to fill the space — fidgeting, murmuring, exchanging glances. After 30 seconds or so, this noise died down too, settling into a deeper silence still. Once another half-minute had passed, I rang the gong again.</p><p>We then proceeded to have one of our most efficient sprint planning sessions in weeks. We even finished 15 minutes early. Not a bad return on investment for one minute of silence.</p><p>This practice was an experiment in management, one of many we’ve tried within <a href="http://www.linkedin.com/company/trainline">Trainline’s</a> web team. Now looking back at our journey, I’d like to share why we risked breaking with the orthodox agile formula and what we’ve learned from 15 months of testing.</p><h4>Seeking a Simpler Way</h4><p>As a product manager, I started experimenting with unconventional management methods out of a longing for a simpler, more soulful way to work.</p><p>When I first discovered Scrum from gurus like Jeff Sutherland and Roman Pichler, I thought I’d found the answer to all the ills of traditional management. Scrum offered a complete solution to so many of the frustrations I had with waterfall-style planning, and I bought into the new system wholeheartedly. I prioritised backlogs, estimated work, and produced nice burndown charts which made me feel like our team was making progress.</p><p>However, I soon found that Scrum’s playbook was missing some pages. Its ceremonies and techniques created lots of velocity but not a lot of meaning. I’d fallen into the trap of getting fixated on accelerating output, which ultimately distracted from the real work — solving problems for people. Working this way ultimately made me feel I was running a Fordian feature factory — productive yet somehow empty.</p><p>When I joined Trainline in October 2015 as the product manager for the web, I was looking for a more soulful way to manage a team. This led me to discovering with what I like to call <em>evolutionary management</em>.</p><h4>Discovering Evolutionary Management</h4><p>In his 2014 book, <em>Reinventing Organisations</em>, author Frederick Laloux documents 12 organisations around the world operating from radically new management principles — and what makes these teams’ practices an evolutionary leap beyond inherited management philosophies.</p><p>As detailed in his research, most modern corporations operate from what Laloux calls <em>Achievement-Orange</em>, a worldview which sees organisations (and people) as machines designed to maximise economic output. This mechanical metaphor permeates everyday business language through phrases like “pulling levers,” “resourcing initiatives,” and “optimising productivity.” Words like these define the relationship between people and their work as mechanical parts with functions to be predicted and controlled.</p><p>While Achievement-Orange practices succeed at getting results, these results often come at the expense of the individual, who can often feel like a replaceable cog in an impersonal machine.</p><p>Beyond Achievement-Orange, there is <em>Pluralistic-Green,</em> a worldview which builds on Orange’s foundations but adds three breakthroughs — employee empowerment, a values-driven culture, and stakeholder value. Pluralistic-Green organisations feel less like a machine and more like a family. These organisations include industry leaders like Southwest Airlines and Ben and Jerry’s, companies characterised by extraordinary employee engagement and customer satisfaction.</p><p>While Pluralistic-Green organisations are among the most successful in the world, they retain a pyramidal management hierarchy at odds with their “empowered” culture. This contradiction creates tension which limits individuals from bringing their full intelligence and initiative to work.</p><p>What lies beyond Pluralistic-Green?</p><p>Laloux discovered many companies operating in a way which integrates and expands on the previous stages, a model he calls <em>Evolutionary-Teal</em>. These organisations see themselves not as machines or families but as <em>living systems</em>, organisms which are internally integrated yet always growing with respect to their environment. Three breakthroughs characterise this stage of development:</p><p>1)<em> Self-management</em>. Teams operate with fluid systems of distributed authority in which each person has the power to make meaningful decisions. Rather than concentrating power and control at the top of a pyramid, self-managed teams have agreements in place which make everyone powerful.</p><p>2)<em> Wholeness</em>. Teams have practices in place which allow each person to drop the masks they wear at work and be completely themselves. Letting go of the ego not only releases enormous energy for individuals; it also creates a safe space which leaves room for extraordinary innovation. When people feel free to say what they truly feel, they bring their full intelligence to work and generate the best ideas.</p><p>3)<em> Evolutionary Purpose</em>. Teams tend not to work from rigid strategy or planning documents, artefacts symptomatic of an Achievement-Orange predict and control management philosophy. Instead, they align to a shared purpose and adjust every day to move toward that purpose, a sense and respond way of operating.</p><p>The promises of Evolutionary-Teal seemed to address many of my problems with conventional agile methodologies. So with that hope, the web team and I stepped into the unknown and tried installing practices from this new model.</p><p>In next week’s blog, discover what we found…</p><h4>About the author</h4><p>Ian is a senior product owner at Trainline passionate about building great products, teams, and organisations. Born and raised in the San Francisco Bay Area, he has been working and learning proper English in London for the past six years. Ian has an MSc in Decision Sciences from the London School of Economics and a BA in Cognitive Science from Yale University.</p><p><a href="http://engineering.thetrainline.com/2017/04/03/practicing-evolutionary-management-at-trainline-experiments-in-self-management-and-wholeness/">Part 2: Practicing Evolutionary Management at Trainline: Experiments in Self-Management and Wholeness &gt;&gt;</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a76e793360ce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/practicing-evolutionary-management-at-trainline-the-journey-to-evolutionary-teal-and-beyond-a76e793360ce">Practicing Evolutionary Management at Trainline: The Journey to Evolutionary-Teal and Beyond…</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[There and back again: a {json:api} tale at Trainline]]></title>
            <link>https://medium.com/trainline/there-and-back-again-a-json-api-tale-at-trainline-f6b4d184c153?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/f6b4d184c153</guid>
            <category><![CDATA[csharp]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[development]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Thu, 23 Feb 2017 11:01:34 GMT</pubDate>
            <atom:updated>2017-07-04T14:54:34.815Z</atom:updated>
            <content:encoded><![CDATA[<p>Our team was tasked with creating a new RESTful API to help reduce the amount of logic that is implemented in potentially different ways across our front-end channels. One item discussed early on was if we should try using <a href="http://jsonapi.org/">JSON API</a> to structure our responses.</p><p>Other teams within Trainline have had some success creating JSON-API-based services in Ruby, and we saw no reason why our C# implementation would be any less successful. This blog post is an attempt to tell the story of the journey we took and where we ended up.</p><p><em>For a full explanation of what JSON API is, see the project site (</em><a href="http://jsonapi.org/"><em>http://jsonapi.org</em></a><em>)</em></p><h4>Why join such a fellowship?</h4><p>Firstly, why would we consider JSON API for responses when, surely, standard JSON representation of our classes is simple and ‘just works’?</p><ol><li>We simply don’t want to spend time discussing the structure of our response and how best to optimise it. JSON API gives us a way of having a defined response for each endpoint without having to re-invent the wheel</li><li>Resource objects. JSON API provides a way of linking primary resources. These can be displayed within the ‘included’ section of the response, to minimise requests, or just linked in order to minimise payload size. Given the data we are representing had numerous external resources, this appealed to us more than any other aspect of JSON API</li><li>At the end of the day, it’s just another way of serializing data. We figured we can switch serialization methods easily enough and so why not try…</li></ol><p>As with all these things, there are of course trade-offs that need to be made for these advantages</p><ol><li>Readability: There’s no other way to say it, but compared to a nice readable standard JSON output, JSON API is ugly! It feels like we are turning JSON into SOAP…</li><li>Performance: Essentially, outputting JSON API requires mapping from nice C# objects to the objects in the correct formatting before serializing. That means that the whole mapping step is additional processing that needs to happen, which has a knock-on effect on performance. Here is some benchmarking we did, serializing a very simplified version of our model:</li></ol><figure><img alt="serialization_benchmark" src="https://cdn-images-1.medium.com/max/558/0*3F_SaJ4uPvdOLDVa.png" /></figure><h4>Implementation</h4><p>The project site has a list of .NET server libraries which can be used to implement JSON API, so we started a spike to consider which option would work best for our scenario:</p><p>(<a href="http://jsonapi.org/implementations">http://jsonapi.org/implementations</a>)</p><figure><img alt="jsonapi_implementations" src="https://cdn-images-1.medium.com/max/763/0*3pWUI15UXMQ9dX1O.png" /></figure><p>What quickly became apparent, is that most of these libraries would not support the JSON API output we were attempting to create. We believe that this is due to that fact that JSON API started as a group of guidelines and then evolved into a strict specification by version 1. The libraries are still catching up with these updates. Some common issues were:</p><ul><li>Top level ‘included’ node not supported</li><li>Resource objects with external links not supported</li><li>Complex types are not always supported as an ‘attribute’</li></ul><h4>NJsonApi</h4><p>Eventually, we discovered that <a href="https://github.com/jacek-gorgon/NJsonApi">NJsonApi</a> provided the best option for us as it created the desired output with simple setup, integration into ASP.NET WebApi and extensibility. We were able to set up the mapping details and bootstrapping in the WebApiConfig, so any reflection needed by NJsonApi to map to JSON API would be done on initialisation of the service.</p><p>As we set up the more complex object, we discovered the need for these extensions / workarounds:</p><ul><li>Every custom object requires mapping configuration which gets quite verbose and has a lot of duplication in our case, given that we want to handle all resource objects in the same way. We resolved this with a set of extensions to the NJsonApi ConfigurationBuilder to allow automated configuration when classes implement a specific interface or attribute</li><li>To specify serialization options (case, enums etc), we had to override the default serializer</li><li>Unable to serialize IEnumerable&lt;T&gt; types. There is an issue in the GetItemType method <a href="https://github.com/jacek-gorgon/NJsonApi/blob/b691bd194d657ebf4acb028de91e0a7c45d338a3/NJsonApi/ResourceConfigurationBuilder.cs">here</a> which means that only collection interfaces that implement IEnumerable&lt;T&gt; are supported rather than the IEnumerable&lt;T&gt; itself. We worked around this by using ICollection&lt;T&gt; or something similar, but if we moved forward with NJsonApi it could be fixed with a simple pull request</li><li>The JsonApiActionFilter swallows any exceptions so and then falls back to the standard JSON serialization — which makes debugging a little trickier</li></ul><h4>Deserialization</h4><p>Now we had our objects serializing nicely into JSON API, surely, it’s a simple case to deserialize back to those objects you say? Sadly, this is not the case. The NJsonApi deserialization did not seem to support the compound documents with included resources. Fortunately, there is a library available that only does deserialization and supports all these things: <a href="https://github.com/l8nite/JsonApiNet">JsonApiNet</a></p><p>Sadly, JsonApiNet, whilst excellent at deserializing from our JSON API to C# objects, provided new and exciting challenges:</p><ul><li>Because we now had a separate library for serialization and deserialization we had to create a new formatter for deserialization which needs to be at the top of the formatter collection, then the NJsonApi formatter needs to be the next in the list followed by the standard JSON formatter.</li><li>Performance: JsonApiNet uses reflection at deserialization time and the performance benchmarks we got were much slower than standard JSON:</li></ul><figure><img alt="deserialization_benchmark" src="https://cdn-images-1.medium.com/max/624/0*2fQob5cepll0YyN_.png" /></figure><ul><li>GNU Licence: The limitations of the GNU licence mean it is better for us to not use open source software under this licence for commercial application</li></ul><p>In the end, we implemented a custom solution for deserialization which involved deserializing to a ‘jsonapi’ C# object and then mapping from that to our original objects. Whilst this is very performant as there is no reflection necessary, it does make for tedious and hard to maintain code so a more performant reflection version would have to be created at some point.</p><h4>The Return of the (James Newton) King</h4><p>At this point, we took stock of the situation in the end-of-sprint retro and re-assessed the viability of JSON API. We decided that, whilst our service response did indeed provide a good candidate for the advantages of JSON API, we would not pursue it at this point for the following reasons</p><ul><li>We were spending longer on the JSON API serialization than we were on solving the engineering problems that our project is trying to address</li><li>We already supported JSON as well as JSON API to demo work in progress in a more readable way</li><li>Removing the JSON API work would not take very long at all and not much work had been done to consume it yet</li><li>It was looking more and more likely that we would need to create our own JSON API library, but there is no reason that it would need to be done before the project work. The library can be built in isolation and then we can always switch back to JSON API at a later date — it’s just serialization after all…</li><li>JSON is simple and just works</li></ul><h4>About the author</h4><p>Mike Reeves is a Software Engineer at Trainline working mainly with C# on back-end services. He likes good whisky, good books and good <strong><em>enough</em></strong><em> </em>code!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f6b4d184c153" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/there-and-back-again-a-json-api-tale-at-trainline-f6b4d184c153">There and back again: a {json:api} tale at Trainline</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My First Week at Trainline]]></title>
            <link>https://medium.com/trainline/my-first-week-at-trainline-6f780639e040?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/6f780639e040</guid>
            <category><![CDATA[life-lessons]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[diary]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Wed, 08 Feb 2017 14:46:05 GMT</pubDate>
            <atom:updated>2017-07-04T14:34:56.763Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/491/0*cKKObm7JaBvhnPSt.jpg" /></figure><p>I was selected for the Trainline graduate scheme right after university and the first few weeks here have been a new chapter in my life. It might be somewhat confusing for most people how an Aerospace Engineering graduate finds himself starting out at a tech company that deals with trains. Software was always a key part of my work in engineering and I have always wanted to learn the tricks of the trade in this sector. What better way for me to achieve these goals than to join one of the most innovative e-commerce companies in Europe? And, more specifically, in a team which is responsible for so much interaction with the trains on the ground?</p><p><strong>Welcome to Trainline</strong></p><p>My first week at Trainline was quite a blur, as might be expected when you want to get up to speed on the functioning of a very fast-moving organisation. They really helped by arranging induction sessions for the new joiners, each dealing with a specific aspect of the company. I found these to be very valuable in giving me a bird’s eye view of the company structure and how the various systems interact with each other. One of the most engaging was the Q&amp;A with our CEO where she shared her vision for Trainline, as it grows globally making it easier for everybody to travel. This really made me excited to be here.</p><p><strong>Routemaster: the most sensibly named team at Trainline</strong></p><p>The Routemaster team deals with those bits of Trainline that integrate right into the UK’s rail network, most importantly, journey searches. The work here involves an overlap of software and trains. This is also the most aptly-named team, as I found out on my first day when I went to collect my equipment from the IT support team named “Jedi”.</p><p>I found myself straight in at the deep end from day one as I paired with other team members working on actual product development. New joiners are encouraged to deploy something to production in their first week, whether it’s a comment or a line of code. Deploying my first two pieces of work into production in my first week substantially boosted my confidence and made me enjoy the learning experience.</p><p><strong>What we do</strong></p><p>As an engineer, I have found the work environment very engaging. I spend every day collaborating with some of the brightest individuals to solve problems and translate these solutions into good code. Programming itself is often not the majority of the work, a key aspect is to ensure all the different pieces fit well together. Often, you might find yourself concentrating on issues conceptually. Every day is different here at Trainline.</p><p>Besides the programming, the work in Routemaster also requires domain-specific knowledge about the rail network. An induction session dedicated to the UK’s rail network was very helpful. This ‘rail’ side of things is particularly exciting when you realise how close you are to the real-world implications of the problems that you solve on a day-to-day basis.</p><p><strong>Supported Learning</strong></p><p>As exciting as all this is, there is a lot to learn and my team leader was very supportive in helping me set my objectives and organising all the additional training that I needed to fill the gaps in my IT skills. This has added a real structure to everything and makes everything a lot easier.</p><p>Besides this, all the fresh grads are also appointed a mentor. Mentors are purposely selected from other teams to help you to meet people from outside your immediate circle and allow you to be more open. Personally, my mentor is from a team called “Vulcan”, which as the name very intuitively indicates, deals with marketing :-) Furthermore, mentors are usually people who have themselves joined fairly recently and so the experience of being a new starter is fresh in their minds. There are regular mentor-mentee get-togethers, but you can just approach them whenever you want to ask anything related to work or otherwise. A great way to make some friends right from the get-go!</p><p><strong>All work, no play?</strong></p><p>It is not all work at Trainline, this is frankly one of the coolest places to work. Much like a university, there are clubs for you to get involved in. Yoga, salsa (as in doing not eating), board games or you can start your own! Trainline does have a great sense of community. And what a diverse community it is, with people from all over the world working at the company. They also encourage you to take part in Hackathons which is great for honing your skills and having some fun at the same time. As a graduate right out of university, you will fit right in as you can just continue to be a student! There is always something to get involved in here at Trainline.</p><p><strong>Perks of the job</strong></p><p>Also, no article about working at Trainline would be complete without mentioning the numerous perks on offer. While some organisations are content with offering you a vanishing Aston Martin with rocket launchers and expensive watches that explode, we go one step ahead and offer … free breakfast! It is impossible to stress how easy this makes my day. Then there are salary sacrifice schemes for things like gym memberships and bicycles. The location of the London office, right next to Leather Lane, gives you access to some of the city’s most awesome street food right at your doorstep, thus making it possible to look forward to every weekday!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6f780639e040" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/my-first-week-at-trainline-6f780639e040">My First Week at Trainline</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migrating from Oracle Exadata to AWS]]></title>
            <link>https://medium.com/trainline/migrating-from-oracle-exadata-to-aws-b7c7bea3da9d?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/b7c7bea3da9d</guid>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[deployment]]></category>
            <category><![CDATA[data]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[infrastructure-automation]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Wed, 25 Jan 2017 17:56:15 GMT</pubDate>
            <atom:updated>2017-07-04T09:48:13.382Z</atom:updated>
            <content:encoded><![CDATA[<p>Since my <a href="https://youtu.be/8pksNOubvPI">talk at AWS re:Invent</a> in December, we’ve had a lot of questions about how we tackled our Oracle Exadata migration to AWS.</p><p>This post goes through our Oracle migration journey in more detail and also includes some general tips for moving large databases to the Cloud.</p><h4><strong>Our Oracle Exadata Migration</strong></h4><h4><strong>The Challenge</strong></h4><p>Databases running on Exadata are at the core of many big systems and are a common challenge when moving to commodity hardware in the Cloud. Typically, they are big, high performance, and latency sensitive.</p><p>Our primary database was 4TB in size and required 600MB of mixed IO per second. We were fortunate that it was largely read heavy but unlucky in how the applications were using it. The database was called several times during some key user journeys so any extra latency or slow-down would be amplified for our users.</p><p>Another complication, as ever with Oracle, was licensing. We had enough licenses to cover 16 VCPUs in AWS but knew that keeping to this target was going to be tough. One downside of AWS is that you can’t miss performance on 16 cores and just go for 18 or 20 instead. The next size up is 32 cores which would have been painfully expensive!</p><h4><strong>Step 1: AWS Baseline</strong></h4><p>Our first move was to simply throw the database into AWS and get a feel for how it worked.</p><p>We used a specialist tool from Oracle called Real Application Testing (or ‘RAT’) to record 1 hour of live production traffic so we could play it back against the AWS version and compare performance.</p><p>As a starting point, we created an R3.8xLarge instance (32 cores), gave it 4 1TB disks (largest size available at the time) and played back the RAT test.</p><p>Initial results showed the scale of the problem — 33% slower on double the cores.</p><h4><strong>Step 2: Infrastructure Tuning</strong></h4><p>From the baseline is was obvious that the key issue for our particular database was IO throughput rather than CPU or RAM. We were hitting the throughput limits of individual EBS volumes and noticed that a large number of reads were hitting the comparatively expensive EBS volumes when we might be able to cache these better.</p><p>After a fair bit of experimenting, we ended up with the following configuration:</p><ul><li>I2.4xLarge instance (16 cores, IO optimised, more ephemeral storage)</li><li>8 x 500GB EBS volumes (more disks to help Oracle ASM stripe and avoid hitting the throughput limits of any single volume)</li><li>Option set within Oracle to move 400GB of level 2 buffer cache to the faster ephemeral storage</li></ul><p>These changes meant we had an IO optimised AWS Server, avoided single volume throughput limits and were able to serve a large proportion of our read traffic from local instance storage rather than EBS.</p><p>The new results from our RAT testing showed we were now 20% slower than our production database but on a 16 core machine. Overall this was a big step forward.</p><p>A couple of notes:</p><ul><li>In general, we are big fans of AWS’s RDS service. Unfortunately, it wasn’t the right fit for this particular database due to the level of fine tuning we needed access to within Oracle</li><li>We did experiment with PIOPS for the EBS volumes but ultimately found that for us, GP2 offered the best performance/price point. Your mileage may vary, especially if your database is more write heavy.</li></ul><h4><strong>Step 3: Database Tuning</strong></h4><p>Our next step was to review the database itself for optimisations.</p><p>We found we were keeping a longer transaction history in the OLTP database than necessary and so ran clean-up scripts to get rid of this older operational data. The history was already safe in our data warehouse and this simple step helped shrink the database considerably.</p><p>We also took the opportunity to upgrade to the latest version of Oracle to benefit from a few useful performance improvements in the new edition.</p><p>Finally, we tuned some indexes. On Exadata, indexes tend to be removed specifically to benefit from Exadata’s storage cell offloading but on AWS we had to keep analysing the slowest queries from each RAT run and tuning the execution plans to make better use of index scans. In some areas, the direct access from Level 2 flash cache was actually faster than index scans, although this will depend on your queries and workload.</p><p>At this point our RAT test results were around 12% slower than production.</p><h4><strong>Step 4: Application Tuning</strong></h4><p>Knowing that IO was the limiting factor, we did some analysis on the heaviest IO queries coming from our applications. This showed some obvious areas where we could reduce the amount of data being requested or the frequency of calls. This work got added to our Dev team’s migration backlogs and we were soon within the ~5% performance window we agreed would unblock migration to AWS.</p><p>It seems like the sheer power of Exadata has a tendency to make everybody just a little bit lazy. There is no urgency to optimise queries because results get thrown back near instantly even when badly written. The move to AWS has definitely helped serve as a bit of a forcing function to help us identify and optimise a few dodgy queries.</p><h4><strong>Today</strong></h4><p>Since our initial migration we have continued to optimise the infrastructure, database and application usage. Thanks to some amazing and ongoing work by our DBAs and Dev Teams, the key user journeys hitting our database now run 10% faster in AWS than they did on-prem against Exadata!</p><p>Unfortunately, it’s not really possible to get a direct like-for-like comparison of just the database element anymore. There are a lot of different factors that influence overall performance and the database and our use of it have evolved over time. None the less, the database went from being a major problem for our migration to a more flexible and cost effective solution hosted in AWS and providing our customers with a better experience.</p><p>We’re really pleased with how things worked out and would definitely encourage you not be put off if you too have a monster database to move!</p><figure><img alt="monsterdatabase" src="https://cdn-images-1.medium.com/max/544/0*J0OPJ4GmAsAX4Dkf." /></figure><h4><strong>Large Database Migrations — General Strategies</strong></h4><p>The following are some approaches to consider if you’re planning your own Exadata or large database migration.</p><h4><strong>Divide and Conquer</strong></h4><p>First it’s worth validating the assumption that your database really is one database. Many monolithic schemas were created for historical or convenience reasons rather than necessity. It may be there are logical subsets of schema that can be teased apart to reduce the scope of the problem.</p><h4><strong>Shrink and Shift</strong></h4><p>If the database must be kept whole, there are still opportunities for optimisation before migration.</p><p>For example, can the retention period for transactional data be reduced? Is the same period needed for all tables?</p><p>Proper use of indexes can make a big difference to the IO and memory requirements of your queries. The raw power of Exadata can cover for under-optimised indexes and hide problem queries. Finding and fixing these issues can reduce the target requirements in AWS considerably.</p><h4><strong>Modify Apps</strong></h4><p>Database read load can be reduced by:</p><ul><li>Avoiding unnecessary calls and reducing the frequency of required calls</li><li>Minimising the volume of data retrieved by queries</li><li>Making greater use of application level caching</li><li>Working from read-replicas rather than a single master</li></ul><p>Write heavy databases are harder to deal with. One strategy, if some writes can afford to be asynchronous, is to create a separate writer process. Suitable updates can then be posted to the writer’s queue and persisted to the database at a different speed to time-sensitive writes.</p><h4><strong>Change the Database Engine</strong></h4><p>One pretty new option worth considering is <a href="https://aws.amazon.com/about-aws/whats-new/2016/11/announcing-postgresql-compatibility-for-amazon-aurora/">PostgresSQL for Aurora RDS</a>.</p><p>Provided you aren’t using too many Oracle specific stored procedures, triggers etc. then migration should be relatively painless. Once there, Aurora can support impressive scale and speed. Aurora is really shaping up to be an impressive offering so do check it out if you haven’t already!</p><h4><strong>Go Native or Go Home</strong></h4><p>Sometimes the right choice is to give up. If your database is too big, too Oracle specific, too complicated to move to AWS, then chances are it is also the cause of significant friction and risk in your development cycle.</p><p>In these cases, starting from scratch and running the 2 systems in parallel is a good approach. You can build a new Cloud-native solution in AWS whilst verifying the results against the original system. Once you have enough confidence in the new system you can quietly lead your Exadata behind the cow shed.</p><p>In fact, you may be able to do this earlier than expected if you bring the new system online in stages. Once some load has moved on to the new system, what’s left on Exadata may be small enough to migrate using one of the other approaches above.</p><h4>Summary</h4><p>There are a number of options available to help move large databases to the public Cloud. What at first may look like an intractable problem can in most cases be broken down and handled by some combination of the different techniques.</p><p>Having your databases in AWS also comes with a raft of benefits in terms of agility, cost, flexibility etc. We’ve certainly found it well worth the effort. Good luck and happy migrations!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b7c7bea3da9d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/migrating-from-oracle-exadata-to-aws-b7c7bea3da9d">Migrating from Oracle Exadata to AWS</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Trainline replatforming: our front-end journey]]></title>
            <link>https://medium.com/trainline/trainline-replatforming-our-front-end-journey-9922fb218cf6?source=rss-54ce459010e6------2</link>
            <guid isPermaLink="false">https://medium.com/p/9922fb218cf6</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[css]]></category>
            <category><![CDATA[front-end-development]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Trainline Team]]></dc:creator>
            <pubDate>Fri, 13 Jan 2017 11:45:12 GMT</pubDate>
            <atom:updated>2017-07-04T10:24:29.937Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="screen-shot-2016-12-16-at-12-47-28" src="https://cdn-images-1.medium.com/max/1024/0*-6iSpgtXYtFLnA7A.png" /></figure><p>We recently started working on rebuilding the desktop version of the Trainline website. It is a big deal for the front-end engineering team because we have to make sure every choice is justified so that the user experience is never compromised. I am writing this blog post to explain how we went about selecting our front-end tech stack and why we made these choices.</p><h4>How we approached it</h4><p>First, it seemed obvious for us to use the following JavaScript dependencies as a base for our front-end stack:</p><ul><li>React</li><li>React-router</li><li>Redux</li><li>Webpack</li></ul><p>Things became more complicated when we had to discuss the following topics:</p><ul><li>Which library to manage side-effects: Redux-saga, Redux-observable or Redux-thunk ?</li><li>Is static typing valuable for front-end development and, if so, should we use Flow or TypeScript?</li><li>Which library should we use for styling in React: CSS-modules with PostCSS or Aphrodite?</li><li>Is server-side rendering valuable for performance and SEO?</li><li>Should we keep our control components (buttons, drop-downs …) in a separate git repository?</li></ul><p>This is a lot to bring to the table and we spent a lot of time deliberating. Due to the number of users of our website, every choice has to be carefully considered. For example, we had to make sure that every library we selected is well maintained and fits well with the other ones.</p><p>For that, we did some spikes (short, focused investigations) on each of the above points. It would take too long to discuss each one in detail, but here, I will cover the two most controversial.</p><h4>Static typing in JavaScript — a long debate</h4><figure><img alt="scream" src="https://cdn-images-1.medium.com/max/300/0*Ur_gam9F85KXaWrh." /></figure><p>Today, there are two main technologies which bring static typing to Javascript:</p><ul><li>TypeScript (maintained by Microsoft)</li><li>Flow (maintained by Facebook)</li></ul><p>Both provide some common basics feature of static typings but are actually quite different in their implementation. To us Typescript seemed to be the most adapted and, to be honest, we didn’t focus too much on Flow, mainly because the team was already used to TypeScript. As opposed to Flow, Typescript is a compiler, and we are using it as a replacement for Babel to compile to ES5 which also simplifies our stack.</p><p>Now the main debate in the team was why we should be using static typings with TypeScript. We had a look at multiple articles to help us out here, such as:</p><ul><li><a href="https://medium.com/javascript-scene/the-shocking-secret-about-static-types-514d39bf30a3#.9djek1y6s">The Shocking Secret About Static Types</a></li><li><a href="https://medium.freecodecamp.com/when-should-i-use-typescript-311cb5fe801b#.qbywfme08">Why Should I Use TypeScript ?</a></li><li><a href="https://djcordhose.github.io/flow-vs-typescript/2016_hhjs.html#/">FLOW VS TYPESCRIPT TYPE SYSTEMS FOR JAVASCRIPT</a></li></ul><p>Each of these covers a lot of valuable opinions, but I will try to summarise the team opinion on this. I personally think that the most important point is that TypeScript helps us to catch some static type related bugs. This is even more so since TypeScript 2.0 came out with the strictNullChecks compiler option.</p><p>Next, having static types helps us to understand the shape of the data at any time. By just looking at a TypeScript interface, we already know what is at our disposal. We don’t need to look at the API documentation, everything is there in the same codebase. This way, we only focus on the IDE and we spend less time in the browser trying to debug using console.log or break points. To make sure that we benefitted from this, we decided to be strict and force everyone to define an accurate type by enabling noImplicitAny flag.</p><p>Another nice point that TypeScript provides, which is not always shown, is that it gives a proper “auto-completion” and “jump to definition” and this is very valuable as well. Now that I am used to the syntax, my productivity has increased a lot by just jumping between files, so I don’t spend time hunting around the files trying to search for any information.</p><p>That being said, one downside of TypeScript is that we rely on the community for the type definition files. If a library doesn’t have a type definition file you either have to write it yourself or you have to use it without typings. To me this is not a big deal and shouldn’t be a big worry, as the community around TypeScript is big enough that all the most-used libraries already have their type definition files. If the library you are using doesn’t have any, you should think twice about using it.</p><h4>Styling in react, inline-style with Aphrodite vs CSS modules</h4><p>And now the second most controversial topic our team had to face. We were quite literally divided in two around this one. In the end, we decided to go with Aphrodite and here is why:</p><ul><li>It is easier to apply dynamic styles with inline styles rather than applying a css class as a string depending on some logic</li><li>Aphrodite provides real CSS pseudo-selectors (`:hover`, `:focus` etc.) that inline styles alone do not cover</li><li>Because CSS involves cascading styles, the rules are not scoped to a component and this can lead to some unexpected styling issues.</li><li>Aphrodite is compatible with server-side rendering</li><li>When using Aphrodite with server side rendering you can extract the CSS styles into a separate file so that the browser can cache it.</li><li>Aphrodite provides granular font importing. If the styles in your page don’t reference a font defined by Aphrodite, it does not get inserted (although Chrome already behaves this way).</li></ul><p>These arguments were sufficient for us to choose Aphrodite as a styling library over css-module, but there are plenty of other elegant solutions worth trying if Aphrodite doesn’t fit your needs. At the moment I would suggest having a look at <a href="https://github.com/threepointone/glamor">Glamor</a> and the new shiny <a href="https://github.com/styled-components/styled-components">Styled components</a> which is, I think, the most “React way” to tackle the subject.</p><p>PS: If you want to have a look at Styled components, at Trainline we have used it for the website of our <a href="https://github.com/philpl/reactivate">Reactivate</a> meet up.</p><h4>The challenges coming up</h4><figure><img alt="pqytbp7ek1dqs" src="https://cdn-images-1.medium.com/max/500/0*8YJMXGR-Vp2LN4rx.gif" /></figure><p>Once we had tested everything we wrote a boilerplate containing the full software stack. We now have around 20 developers working full-time on the desktop site using Typescript and Aphrodite and haven’t found any limitations so far.</p><p>Although it may take a bit of time for new joiners to get up to speed on all these technologies, I think it is good for the business in the long term. Enforcing some guidelines with these tools helps to reduce the impact that technical debt could have on the project.</p><p>We now have to make sure we share the knowledge with each other in an effective and efficient way and this is the upcoming challenge for the team. Sharing knowledge well is particularly important around Typescript and RxJs as these two technologies are quite disruptive.</p><p>If you liked this blog post, or if you are interested about the tools we are using, please come along to our next <a href="https://reactivate.london/">React meetup</a> and join our <a href="https://www.meetup.com/Reactivate-London/">Reactivate meetup</a> group!</p><h4>About the author</h4><p>Alexandre Rieux is a front-end developer mainly working with React, sometimes playing with Swift, or learning Haskell and Elm (FP enthusiast). He is co-organiser of <a href="https://reactivate.london/">reactivate.london</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9922fb218cf6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trainline/trainline-replatforming-our-front-end-journey-9922fb218cf6">Trainline replatforming: our front-end journey</a> was originally published in <a href="https://medium.com/trainline">The Trainline Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>