<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="http://anjana.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="http://anjana.dev/" rel="alternate" type="text/html" /><updated>2024-02-05T18:04:42+00:00</updated><id>http://anjana.dev/feed.xml</id><title type="html">Anjana Sofia Vakil</title><subtitle>Developer Educator &amp; Software Engineer</subtitle><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><entry><title type="html">Notes from KatsConf2</title><link href="http://anjana.dev/blog/katsconf2/" rel="alternate" type="text/html" title="Notes from KatsConf2" /><published>2017-02-19T00:00:00+00:00</published><updated>2017-02-19T00:00:00+00:00</updated><id>http://anjana.dev/blog/katsconf2</id><content type="html" xml:base="http://anjana.dev/blog/katsconf2/">&lt;p&gt;Hello from Dublin! Yesterday I had the privilege of attending &lt;a href=&quot;http://www.katsconf.com/&quot;&gt;KatsConf2&lt;/a&gt;, a functional programming conference put on by the fun-loving, welcoming, and crazy-well-organized &lt;a href=&quot;https://twitter.com/functionalkats&quot;&gt;@FunctionalKats&lt;/a&gt;. It was a whirlwind of really exciting talks from some of the best speakers around. Here’s a glimpse into what I learned.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There’s no such thing as an objectively &lt;a href=&quot;#perfect&quot;&gt;perfect programming language&lt;/a&gt;: all languages make tradeoffs. But it is possible to find/design a language that’s more perfect for you and your project’s needs.&lt;/li&gt;
  &lt;li&gt;Automation, automation, automation:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#generative&quot;&gt;Generative programming&lt;/a&gt; lets you write high-level code that generates low-level code&lt;/li&gt;
      &lt;li&gt;Program &lt;a href=&quot;#derivation&quot;&gt;derivation&lt;/a&gt; and &lt;a href=&quot;#synthesis&quot;&gt;synthesis&lt;/a&gt; let you write specifications/tests and leave it to the computer to figure out the code&lt;/li&gt;
      &lt;li&gt;(Boring!) code rewriting tasks can be &lt;a href=&quot;#rug&quot;&gt;automated&lt;/a&gt; too&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#relational&quot;&gt;Relational programming&lt;/a&gt;, &lt;a href=&quot;#total&quot;&gt;Total programming and Type-Driven Development&lt;/a&gt; are (cool/mindblowing) things.&lt;/li&gt;
  &lt;li&gt;You can do &lt;a href=&quot;#web&quot;&gt;web programming with FP&lt;/a&gt; - and interestingly, even in a &lt;a href=&quot;#total&quot;&gt;total language like Idris&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I took a bunch of notes during the talks, in case you’re hungering for more details. But &lt;a href=&quot;https://twitter.com/jessitron&quot;&gt;@jessitron&lt;/a&gt; took amazing graphical notes that I’ve linked to in the talks below, so just go read those!&lt;/p&gt;

&lt;p&gt;And for the complete experience, check out this storify &lt;a href=&quot;https://twitter.com/whykay&quot;&gt;Vicky Twomey-Lee&lt;/a&gt;, who led a great ally skills workshop the evening before the conference, made of the &lt;a href=&quot;https://twitter.com/hashtag/KatsConf2?src=hash&quot;&gt;#KatsConf2&lt;/a&gt; tweets:&lt;/p&gt;

&lt;div class=&quot;storify&quot;&gt;&lt;iframe src=&quot;//storify.com/whykay/kats-conf-2/embed?template=slideshow&quot; width=&quot;100%&quot; height=&quot;750&quot; frameborder=&quot;no&quot; allowtransparency=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;script src=&quot;//storify.com/whykay/kats-conf-2.js?template=slideshow&quot;&gt;&lt;/script&gt;&lt;noscript&gt;[&lt;a href=&quot;//storify.com/whykay/kats-conf-2&quot; target=&quot;_blank&quot;&gt;View the story &quot;Kats Conf 2&quot; on Storify&lt;/a&gt;]&lt;/noscript&gt;&lt;/div&gt;

&lt;p&gt;Hopefully this gives you an idea of what was said and which brain-exploding things you should go look up now! Personally it opened up a bunch of cans of worms for me - definitely a lot of the material went over my head, but I have a ton of stuff to go find out more (i.e. the first thing) about.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: The (unedited!!!) notes below represent my initial impressions of the content of these talks, jotted down as I listened. They may or may not be totally accurate, or precisely/adequately represent what the speakers said or think, and the code examples are almost certainly mistake-ridden. Read at your own risk!&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-origin-story-of-functionalkats&quot;&gt;The origin story of FunctionalKats&lt;/h2&gt;

&lt;p&gt;FunctionalKatas =&amp;gt; FunctionalKats =&amp;gt; (as of today) FunctionalKubs&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Meetups in Dublin &amp;amp; other locations&lt;/li&gt;
  &lt;li&gt;Katas for solving programming problems in different functional languages&lt;/li&gt;
  &lt;li&gt;Talks about FP and related topics&lt;/li&gt;
  &lt;li&gt;Welcome to all, including beginners&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-perfect-language&quot;&gt;&lt;a name=&quot;perfect&quot;&gt;&lt;/a&gt;The Perfect Language&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bodil Stokke @bodil&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-cards=&quot;hidden&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Bodil&amp;#39;s opinions on the Perfect Language. &lt;a href=&quot;https://twitter.com/hashtag/katsConf2?src=hash&quot;&gt;#katsConf2&lt;/a&gt;&lt;br /&gt;Rather noninflammatory, it must be early in the morning &lt;a href=&quot;https://t.co/KsqGAKubpd&quot;&gt;https://t.co/KsqGAKubpd&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jessica Kerr (@jessitron) &lt;a href=&quot;https://twitter.com/jessitron/status/832913621181018112&quot;&gt;February 18, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;What would the perfect programming language look like?&lt;/p&gt;

&lt;p&gt;“MS Excel!”
“Nobody wants to say ‘JavaScript’ as a joke?”
“Lisp!”
“I know there are Clojurians in the audience, they’re suspiciously silent…”&lt;/p&gt;

&lt;p&gt;There’s no such thing as the perfect language; Languages are about compromise.&lt;/p&gt;

&lt;p&gt;What the perfect language actually is is a personal thing.&lt;/p&gt;

&lt;p&gt;I get paid to make whatever products I feel like to make life better for programmers. So I thought: I should design the perfect language.&lt;/p&gt;

&lt;p&gt;What do I want in a language?&lt;/p&gt;

&lt;h3 id=&quot;it-should-be-hard-to-make-mistakes&quot;&gt;It should be hard to make mistakes&lt;/h3&gt;

&lt;p&gt;On that note let’s talk about JavaScript.
It was designed to be easy to get into, and not to place too many restrictions on what you can do.
But this means it’s easy to make mistakes &amp;amp; get unexpected results (cf. crazy stuff that happens when you add different things in JS).
By restricting the types of inputs/outputs (see TypeScript), we can throw errors for incorrect input types - error messages may look like the compiler yelling at you, but really they’re saving you a bunch of work later on by telling you up front.&lt;/p&gt;

&lt;p&gt;Let’s look at PureScript&lt;/p&gt;

&lt;p&gt;Category theory!
Semiring: something like addition/multiplication that has commutativity (a+b == b+a).
Semigroup: …?&lt;/p&gt;

&lt;h3 id=&quot;there-should-be-no-ambiguity&quot;&gt;There should be no ambiguity&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1 + 2 * 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;vs.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(+ 1 (* 2 3))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Pony: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1 + (2 * 3)&lt;/code&gt;  – have to use parentheses to make precedence explicit&lt;/p&gt;

&lt;h3 id=&quot;it-shouldnt-make-you-think&quot;&gt;It shouldn’t make you think&lt;/h3&gt;

&lt;p&gt;Joe made a language at Ericsson in the late 80’s called “Erlang”. This is a gif of Joe from the Erlang movie. He’s my favorite movie star.&lt;/p&gt;

&lt;p&gt;Immutability: In Erlang, values and variable bindings never change. At all.&lt;/p&gt;

&lt;p&gt;This takes away some cognitive overhead (because we don’t have to think about what value a variable has at the moment)&lt;/p&gt;

&lt;p&gt;Erlang tends to essentially fold over state: the old state is an input to the function and the new state is an output.&lt;/p&gt;

&lt;h3 id=&quot;the-abstraction-ceiling&quot;&gt;The “abstraction ceiling”&lt;/h3&gt;

&lt;p&gt;This term has to do with being able to express abstractions in your language.&lt;/p&gt;

&lt;p&gt;Those of you who don’t know C: you don’t know what you’re missing, and I urge you not to find out.
If garbage collection is a thing you don’t have to worry about in your language, that’s fantastic.&lt;/p&gt;

&lt;p&gt;Elm doesn’t really let you abstract over the fact that e.g. map over array, list, set is somehow the same type of operation. So you have to provide 3 different variants of a function that can be mapped over any of the 3 types of collections.
This is a bit awkward, but Elm programmers tend not to mind, because there’s a tradeoff: the fact that you can’t do this makes the type system simple so that Elm programmers get succinct, helpful error messages from the compiler.&lt;/p&gt;

&lt;p&gt;I was learning Rust recently and I wanted to be able to express this abstraction. If you have a Collection trait, you can express that you take in a Collection and return a Collection. But you can’t specify that the output Collection has to be the same type as the incoming one. Rust doesn’t have this ability to deal with this, but they’re trying to add it.&lt;/p&gt;

&lt;p&gt;We can do this in Haskell, because we have &lt;em&gt;functors&lt;/em&gt;. And that’s the last time I’m going to use a term from category theory, I promise.&lt;/p&gt;

&lt;p&gt;On the other hand, in a language like Lisp you can use its metaprogramming capabilities to raise the abstraction ceiling in other ways.&lt;/p&gt;

&lt;h3 id=&quot;efficiency&quot;&gt;Efficiency&lt;/h3&gt;

&lt;p&gt;I have a colleague and when I suggested using OCaml as an implementation language for our utopian language, she rejected it because it was 50% slower than C.&lt;/p&gt;

&lt;p&gt;In slower languages like Python or Ruby you tend to have performance-critical code written in the lower-level language of C.&lt;/p&gt;

&lt;p&gt;But my feeling is that in theory, we should be able to take a language like Haskell and build a smarter compiler that can be more efficient.&lt;/p&gt;

&lt;p&gt;But the problem is that we’re designing languages that are built on the lambda calculus and so on, but the machines they’re implemented on are not built on that idea, but rather on the Von Neumann architecture. The computer has to do a lot of contortions to take the beautiful lambda calculus idea and convert it into something that can run on an architecture designed from very different principles. This obviously complicates writing a performant and high-level language.&lt;/p&gt;

&lt;p&gt;Rust wanted to provide a language as high-level as possible, but with zero-cost abstractions. So instead of garbage collection, Rust has a type-system-assisted kind of clean up. This is easier to deal with than the C version.&lt;/p&gt;

&lt;p&gt;If you want persistent data structures a la Erlang or Clojure, they can be pretty efficient, but simple mutation is always going to be more efficient. We couldn’t do PDSs natively.&lt;/p&gt;

&lt;p&gt;Suppose you have a langauge that’s low-level enough to have zero-cost abstractions, but you can plug in something like garbage collection, currying, perhaps extend the type system, so that you can write high-level programs using that functionality, but it’s not actually part of the library. I have no idea how to do this but it would be really cool.&lt;/p&gt;

&lt;h3 id=&quot;summing-up&quot;&gt;Summing up&lt;/h3&gt;

&lt;p&gt;You need to think about:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Ergonomics&lt;/li&gt;
  &lt;li&gt;Abstraction&lt;/li&gt;
  &lt;li&gt;Efficiency&lt;/li&gt;
  &lt;li&gt;Tooling (often forgotten at first, but very important!)&lt;/li&gt;
  &lt;li&gt;Community (Code sharing, Documentation, Education, Marketing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your language has to be open source. You can make a proprietary language, and you can make it succeed if you throw enough money at it, but even the successful historical examples of that were eventually open-sourced, which enabled their continued use. I could give a whole other talk about open source.&lt;/p&gt;

&lt;h2 id=&quot;functional-programming--static-typing-for-server-side-web&quot;&gt;&lt;a name=&quot;web&quot;&gt;&lt;/a&gt;Functional programming &amp;amp; static typing for server-side web&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Oskar Wickström @owickstrom&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FP has been influencing JavaScript a lot in the last few years. You have ES6 functional features, libraries like Underscore, Rambda, etc, products like React with FP/FRP at their core, JS as a compile target for functional languages&lt;/p&gt;

&lt;p&gt;But the focus is still client-side JS.&lt;/p&gt;

&lt;p&gt;Single page applications: using the browser to write apps more like you wrote desktop apps before. Not the same model as perhaps the web browser was intended for at the beginning.&lt;/p&gt;

&lt;p&gt;Lots of frameworks to choose from: Angular, Ember, Meteor, React&amp;amp;al. Without JS on the client, you get nothing.&lt;/p&gt;

&lt;p&gt;There’s been talk recently of “isomorphic” applications: one framework which runs exactly the same way on the esrver and the client. The term is sort of stolen &amp;amp;  not used in the same way as in category theory.&lt;/p&gt;

&lt;p&gt;Static typing would be really useful for Middleware, which is a common abstraction but every easy to mess up if dynamically typed. In Clojure if you mess up the middleware you get the Stack Trace of Doom.&lt;/p&gt;

&lt;p&gt;Let’s use extensible records in PureScript - shout out to Edwin’s talk related to this. That inspired me to implement this in PureScript, which started this project called Hyper which is what I’m working on right now in my free time.&lt;/p&gt;

&lt;p&gt;Goals:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Safe HTTP middleware architecture&lt;/li&gt;
  &lt;li&gt;Make effects of middleware explicit&lt;/li&gt;
  &lt;li&gt;No magic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How?&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Track middleware effects in type system&lt;/li&gt;
  &lt;li&gt;leverage extensible records in PureScript&lt;/li&gt;
  &lt;li&gt;Provide a common API for middleware&lt;/li&gt;
  &lt;li&gt;Write middleware that can work on multiple backends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Design&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Conn: sort of like in Elixer, instead of passing a request and returning a response, pass them all together as a single unit&lt;/li&gt;
  &lt;li&gt;Middleware: a function that takes a connection c and returns another connection type c’ inside another type m&lt;/li&gt;
  &lt;li&gt;Indexed monads: similar to a state monad, but with two additional parameters: the type of the state before this action, and the type after. We can use this to prohibit effectful operations which aren’t correct.&lt;/li&gt;
  &lt;li&gt;Response state transitions: Hyper uses phantom types to track the state of response, guaranteeing correctness in response side effects&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;functional-program-derivation&quot;&gt;&lt;a name=&quot;derivation&quot;&gt;&lt;/a&gt;Functional Program Derivation&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;@Felienne&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.felienne.com/slides&quot;&gt;(Amazing, hand-drawn, animal-filled) Slides&lt;/a&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-cards=&quot;hidden&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/hashtag/KatsConf2?src=hash&quot;&gt;#KatsConf2&lt;/a&gt; notes from &lt;a href=&quot;https://twitter.com/Felienne&quot;&gt;@Felienne&lt;/a&gt; TL;DR Math is good practice at being precise. This helps with programming.  &lt;a href=&quot;https://t.co/4QB9xFcLay&quot;&gt;https://t.co/4QB9xFcLay&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jessica Kerr (@jessitron) &lt;a href=&quot;https://twitter.com/jessitron/status/832938376462532609&quot;&gt;February 18, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;Program derivation:&lt;/p&gt;

&lt;p&gt;Problem =&amp;gt; Specification =&amp;gt; Derivation =&amp;gt; Program&lt;/p&gt;

&lt;p&gt;Someone said this is like “refactoring in reverse”&lt;/p&gt;

&lt;p&gt;Generalization: introduce parameters instead of constant values&lt;/p&gt;

&lt;p&gt;Induction: prove something for a base case and a first step, and you’ve proven it for all numbers&lt;/p&gt;

&lt;p&gt;Induction hypothesis: if you are at step n, you must have been at step n-1 before that.&lt;/p&gt;

&lt;p&gt;With these elements, we have a program! We just make an if/else: e.g. for sum(n), if n == 0: return 0; else return sum(n-1) + n&lt;/p&gt;

&lt;p&gt;It all comes down to writing the right specification: which is where we need to step away from the keyboard and think.&lt;/p&gt;

&lt;p&gt;Induction is the basis of recursion.&lt;/p&gt;

&lt;p&gt;We can use induction to create a specification for sorting lists from which we can derive the QuickSort algorithm.&lt;/p&gt;

&lt;p&gt;But we get 2 sorting algorithms for the price of 1: if we place a restriction that we can only do one recursive call, we can tweak the specification to derive InsertionSort, thus proving that Insertion Sort is a special case of Quick Sort.&lt;/p&gt;

&lt;p&gt;I stole this from a PhD dissertation (“Functional Program Derivation” by &lt;inaudible&gt;). This is all based on program derivation work by Djikstra.&lt;/inaudible&gt;&lt;/p&gt;

&lt;p&gt;Takeaways:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Programming == Math. Practicing some basic math is going to help you write code, even if you won’t be doing these kind of exercises on yo ur day-to-day&lt;/li&gt;
  &lt;li&gt;Calculations provide insight&lt;/li&gt;
  &lt;li&gt;Delay choices where possible. Say “let’s assume a solution to this part of the problem” and then go back and solve it later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m writing a whole book on this, if you’re interested in giving feedback on chapter drafts let me know! mail at felienne dot com&lt;/p&gt;

&lt;p&gt;Q&amp;amp;A:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;is there a link between the specification and the complexity of the program? Yes, the specification has implications for implementation. The choices you make within the specification (e.g. caching values, splitting computation) affect the efficency of the program.&lt;/li&gt;
  &lt;li&gt;What about proof assistants? Those are nice if you’re writing a dissertation or whatnot, but if you’re at the stage where you’re practicing this, the exercise is being precise, so I recommend doing this on paper. The second your fingers touch the keyboard, you can outsource your preciseness to the computer.&lt;/li&gt;
  &lt;li&gt;Once you’ve got your specification, how do you ensure that your program meets it? One of the things you could do is write the spec in something like fscheck, or you could convert the specification into tests. Testing and specification are really enriching each other. Writing tests as a way to test your specification is also a good way to go. You should also have some cases for which you know, or have an intuition of, the behavior. But none of this is supposed to go in a machine, it’s supposed to be on paper.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-cake-and-eating-it-or-writing-expressive-high-level-programs-that-generate-fast-low-level-code-at-runtime&quot;&gt;&lt;a name=&quot;generative&quot;&gt;&lt;/a&gt;The cake and eating it: or writing expressive high-level programs that generate fast low-level code at runtime&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nada Amin @nadamin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Distinguish stages of computation&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Program generator: basic types (Int, String, T) are executed at code generation time&lt;/li&gt;
  &lt;li&gt;Rep(Int), Rep(String), Rep(T) are left as variables in the generated code and executed at program run time(?)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Shonan Challenge for Generative Programming - part of the gen. pro. for HPC literature: you want to generate code that is specialized to a particular matrix&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Demo of generating code to solve this challenge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generative Programming Patterns&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Deep linguistic reuse&lt;/li&gt;
  &lt;li&gt;Turning interpreters into compilers
    &lt;ul&gt;
      &lt;li&gt;You can think of the process of staging as something which generates code, think of an interpreter as taking code and additional input and creates a result.&lt;/li&gt;
      &lt;li&gt;Putting them together we get something that takes code and symbolic input, and in the interpret stage generates code which takes actual input, which in the execution stage produces a result&lt;/li&gt;
      &lt;li&gt;This idea dates back to 1971, Futamura’s Partial Evaluation&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Generating efficient low-level code
    &lt;ul&gt;
      &lt;li&gt;e.g. for specialized parsers&lt;/li&gt;
      &lt;li&gt;We can take an efficient HTTP parser from 2000+ lines to 200, with parser combinators&lt;/li&gt;
      &lt;li&gt;But while this is great for performance, it leaves big security holes&lt;/li&gt;
      &lt;li&gt;So we can use independent tools to verify the generated code after the fact&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes generating code is not the right solution to your problem&lt;/p&gt;

&lt;p&gt;More info on the particular framework I’m using: &lt;a href=&quot;http://scala-lms.github.io&quot;&gt;Generative Programming for ‘Abstraction without Regret’&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;rug-an-external-dsl-for-coding-code-transformations-with-scala-parser-combinators&quot;&gt;&lt;a name=&quot;rug&quot;&gt;&lt;/a&gt;Rug: an External DSL for Coding Code Transformations (with Scala Parser-Combinators)&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Jessica Kerr @jessitron, Atomist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The last talk was about abstraction without (performance) regret. This talk is about abstraction without the regret of making your code harder to read.&lt;/p&gt;

&lt;p&gt;Elm is a particularly good language to modify automatically, because it’s got some boilerplate, but I love that boilerplate! No polymorphism, no type classes - I know exactly what that code is going to do! Reading it is great, but writing it can be a bit of a headache.&lt;/p&gt;

&lt;p&gt;As a programmer I want to spend my time thinking about what the users need and what my program is supposed to do. I don’t want to spend my time going “Oh no, i forgot to put that thing there”.&lt;/p&gt;

&lt;p&gt;Here’s a simple Elm program that prints “Hello world”. The goal is to write a program that modifies this existing Elm code and changes the greeting that we print.&lt;/p&gt;

&lt;p&gt;We’re going to do this with Scala. The goal is to generate readable code that I can later go ahead and change. It’s more like a templating engine, but instead of starting with a templating file it starts from a cromulent Scala program.&lt;/p&gt;

&lt;p&gt;Our goal is to parse an Elm file into a parse tree, which give us the meaningful bits of that file.&lt;/p&gt;

&lt;p&gt;The “parser” in parser combinators is actually a combination of lexer and parser.&lt;/p&gt;

&lt;p&gt;Reuse is dangerous, dependencies are dangerous, because they create coupling. (Controlled, automated)  Cut &amp;amp; Paste is a safer solution.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;at which point @jessitron does some crazy fast live coding to write an Elm parser in Scala&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Rug is the super-cool open-source project I get to work on as my day job now! It’s a framework for creating code rewriters&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/jessitron/kats&quot;&gt;Repo for this talk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion: any time my job feels easy, I think “OMG I’m doing it wrong”. But I don’t want to introduce abstraction into my code, because someone else is going to have difficulty reading that. I want to be able to abstract without sacrificing code readability. I can make my job faster and harder by automating it.&lt;/p&gt;

&lt;h2 id=&quot;relational-programming&quot;&gt;&lt;a name=&quot;relational&quot;&gt;&lt;/a&gt;Relational Programming&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Will Byrd&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-cards=&quot;hidden&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Your days are numbered, human programmers. &lt;a href=&quot;https://twitter.com/hashtag/KatsConf2?src=hash&quot;&gt;#KatsConf2&lt;/a&gt; &lt;a href=&quot;https://twitter.com/webyrd&quot;&gt;@webyrd&lt;/a&gt;  &lt;a href=&quot;https://t.co/NK8tRg3sei&quot;&gt;https://t.co/NK8tRg3sei&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jessica Kerr (@jessitron) &lt;a href=&quot;https://twitter.com/jessitron/status/832996092484734977&quot;&gt;February 18, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;There are many programming paradigms that don’t get enough attention. The one I want to talk about today is Relational Programming. It’s somewhat representative of Logic Programming, like Prolog. I want to show you what can happen when you commit fully to the paradigm, and see where that leads us.&lt;/p&gt;

&lt;p&gt;Functional Programming is a special case of Relational Programming, as we’re going to see in a minute.&lt;/p&gt;

&lt;p&gt;What is functional programming about? There’s a hint in the name. It’s about functions, the idea that representing computation in the form of mathematical functions could be useful. Because you can compose functions, you don have to reason about mutable state, etc. - there are advantages to modeling computation as math. functions.&lt;/p&gt;

&lt;p&gt;In relational programming, instead of representing computation as functions we represent it as relations. You can think of a relation in may ways. If you’re familiar with relational databases, or you can think in terms of tuples where we want to reason over sets or collections of tuples, or we can think of it in terms of algebra - like high school algebra - where we have variables representing unknown quantities and we have to figure out their values. We’ll see that we can get FP as a special case - there’s a different set of tradeoffs - but we’ll see that when you commit fully to this paradigm you can get some very surprising behavior.&lt;/p&gt;

&lt;p&gt;Let’s start in our functional world, we’re going to write a little program in Scheme or Racket, a little program to manipulate lists. We’ll just do something simple like append or concatenate. Let’s define append in Scheme:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define append
  (lambda (l s)
    (if (null? l)
        s
        (cons (car l) (append (cdr l) s))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re going to use a relational programming language called Mini Kanren which is basically an extension that has been applied to lots of languages which allows us to put in variables representing values and ask Kanren to fill in those values.&lt;/p&gt;

&lt;p&gt;So I’m going to define &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appendo&lt;/code&gt;. (By convention we define our names ending in -o, it’s kind of a long story, happy to explain offline.)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Writes a bunch of Kanren that we don’t really understand&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now I can do:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (q) (appendo '(a b c) '(d e) q))
((a b c d e))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So far, not very interesting, if this is all it does then it’s no better than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt;.
But where it gets interesting is that I can run it backwards to find an input:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (X) (appendo '(a, b, c) X (a b c d e)))
((d e))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or I can ask it to find N possible inputs:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 2 (X Y) (appendo X Y (a b c d e)))
((a b c d) (e))
((a b c d e) ())
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or all possible inputs:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run* (X Y) (appendo X Y (a b c d e)))
((a b c d) (e))
((a b c d e) ())
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What happens if I do this?&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run* (X Y Z) (appendo X Y Z))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;It will run forever. This is sort of like a database query, except where the tables are infinite.&lt;/p&gt;

&lt;p&gt;One program we could write is an interpreter, an evaluator. We’re going to take an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval&lt;/code&gt; that’s written in MiniKanren, which is called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;evalo&lt;/code&gt; and takes two arguments: the expression to be evaluated, and the value of that expression.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (a) (evalo '(lambda (x) x) q))
((closure x x ()))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (a) (evalo '(list 'a) q))
((a))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Professor &lt;inaudible&gt; wrote a Valentine's day post &quot;99 ways to say 'I love you' in Racket&quot;, to teach people Racket by showing 99 different racket expressions that evaluate to the list `(I love you)`&lt;/inaudible&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 99 (q) (evalo q '(I love you)))
...99 ways...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What about quines: a quine is a program that evaluates to itself. How could we find or generate a quine?&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (q) (evalo q q))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And twines: two different programs p and q where p evaluates to q and q evaluates to p.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (p q) (=/= p q) (evalo p q) (evalo q p))
...two expressions that basically quote/unquote themselves...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What would happen if we run Scheme’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt; in our evaluator?&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (q)
    (evalo
      `(letrec ((append
                  (lambda (l s)
                    (if (null? l)
                        s
                        (cons (car l)
                              (append (cdr l)
                                      s)))))))
          (append '(a b c) '(d e))
      q))
((a b c d e))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But we can put the variable also inside the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; (run 1 (q)
    (evalo
      `(letrec ((append
                  (lambda (l s)
                    (if (null? l)
                        q
                        (cons (car l)
                              (append (cdr l)
                                      s)))))))
          (append '(a b c) '(d e))
      '(a b c d e)))
(s)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now we’re starting to synthesize programs, based on specifications. When I gave this talk at PolyConf a couple of years ago Jessitron trolled me about how long it took to run this, since then we’ve gotten quite a bit faster.&lt;/p&gt;

&lt;p&gt;This is a tool called &lt;a href=&quot;https://github.com/webyrd/Barliman&quot;&gt;Barliman&lt;/a&gt; that I (and Greg Rosenblatt) have been working on, and it’s basically a frontend, a dumb GUI to the interpreter we were just playing with. It’s just a prototype. We can see a partially specified definition - a Scheme function that’s partially defined, with metavariables that are fill-in-the-blanks for some Scheme expressions that we don’t know what they are yet. Barliman’s going to guess what the definition is going to be.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define ,A
    (lambda ,B
      ,C))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now we give Barliman a bunch of examples. Like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(append '() '())&lt;/code&gt; gives &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'()&lt;/code&gt;. It guesses what the missing expressions were based on those examples. The more test cases we give it, the better approximation of the program it guesses. With 3 examples, we can get it to correctly guess the definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Yes, you are going to lose your jobs. Well, some people are going to lose their jobs. This is actually something that concerns me, because this tool is going to get a lot better.&lt;/p&gt;

&lt;p&gt;If you want to see the full dog &amp;amp; pony show, watch the &lt;a href=&quot;https://youtu.be/er_lLvkklsk&quot;&gt;ClojureConj talk&lt;/a&gt; I gave with Greg.&lt;/p&gt;

&lt;p&gt;Writing the tests is indeed the harder part. But if you’re already doing TDD or property-based testing, you’re already writing the tests, why don’t you just let the computer figure out the code for you based on those tests?&lt;/p&gt;

&lt;p&gt;Some people say this is too hard, the search space is too big. But that’s what they said about Go, and it turns out that if you use the right techniques plus a lot of computational power, Go isn’t as hard as we thought. I think in about 10-15 years program synthesis won’t be as hard as we think now. We’ll have much more powerful IDEs, much more powerful synthesis tools. It could even tell you as you’re writing your code whether it’s inconsistent with your tests.&lt;/p&gt;

&lt;p&gt;What this will do for jobs, I don’t know. I don’t know, maybe it won’t pan out, but I can no longer tell you that this definitely won’t work. I think we’re at the point now where a lot of the academic researchers are looking at a bunch of different parts of synthesis, and no one’s really combining them, but when they do, there will be huge breakthroughs. I don’t know what it’s going to do, but it’s going to do something.&lt;/p&gt;

&lt;h2 id=&quot;working-hard-to-keep-things-lazy&quot;&gt;Working hard to keep things lazy&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Raichoo @raichoo&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-cards=&quot;hidden&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;The how, why, and trade offs of non-strictness in Haskell &lt;a href=&quot;https://twitter.com/raichoo&quot;&gt;@raichoo&lt;/a&gt;  &lt;a href=&quot;https://twitter.com/hashtag/KatsConf2?src=hash&quot;&gt;#KatsConf2&lt;/a&gt; &lt;a href=&quot;https://t.co/TWkJjW3gL7&quot;&gt;https://t.co/TWkJjW3gL7&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jessica Kerr (@jessitron) &lt;a href=&quot;https://twitter.com/jessitron/status/833006960207347712&quot;&gt;February 18, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;Without laziness, we waste a lot of space, because when we have recursion we have to keep allocating memory for each evaluated thing. Laziness allows us to get around that.&lt;/p&gt;

&lt;p&gt;What is laziness, from a theoretical standpoint?&lt;/p&gt;

&lt;p&gt;The first thing we want to talk about is different ways to evaluate expressions.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; f x y = x + y
&amp;gt; f (1 + 1) (2 + 2)  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;How do we evaluate this?&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;=&amp;gt; (1 + 1) + (2 + 2)
=&amp;gt; 2 + 4
=&amp;gt; 6  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This evaluation was normal form&lt;/p&gt;

&lt;p&gt;Church-Rosser Theorem: the order of evaluation doesn’t matter, ultimately a lambda expression will evaluate to the same thing.&lt;/p&gt;

&lt;p&gt;But! We have things like non-termination, and termination can only be determined after the fact.&lt;/p&gt;

&lt;p&gt;Here’s a way we can think of types: Let’s think of a Boolean as something which has three possible values: True, False, and “bottom”, which represents not-yet-determined, a computation that hasn’t ended yet. True and False are more defined than bottom (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_|_ &amp;lt;= True&lt;/code&gt;). Partial ordering.&lt;/p&gt;

&lt;p&gt;Monotone functions: if we have a function that takes a Bool and returns a Bool, and x and y are bools where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x &amp;lt;= y&lt;/code&gt;, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f x &amp;lt;= f y&lt;/code&gt;. We can now show that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f _|_ = True&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f x = False&lt;/code&gt; doesn’t work out, because it would have the consequence that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True =&amp;gt; False&lt;/code&gt;, which doesn’t work - that’s a good thing because if it did, we would have solve the halting problem. What’s nice here is that if we write a function and evaluate it in normal order, in the lazy way, then this naturally works out.&lt;/p&gt;

&lt;p&gt;Laziness is basically non-strictness (this normal order thing I’ve been talking about the whole time), and sharing.&lt;/p&gt;

&lt;p&gt;Laziness lets us reuse code and use combinators. This is something I miss from Haskell when I use any other language.&lt;/p&gt;

&lt;p&gt;Honorable mention: Purely Functional Data Structures by Chris Okasaki. When you have Persistent Data Structures, you need laziness to have this whole amortization argument going on. This book introduces its own dialect of ML (lazy ML).&lt;/p&gt;

&lt;p&gt;How do we do laziness in Haskell (in GHC)? At an intermediate stage of compilation called STG, Haskell takes unoptimized code and optimizes it to make it lazy. (???)&lt;/p&gt;

&lt;h2 id=&quot;total-functional-programming&quot;&gt;&lt;a name=&quot;total&quot;&gt;&lt;/a&gt;Total Functional Programming&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Edwin Brady @edwinbrady&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-cards=&quot;hidden&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Type driven development of interactive, total programs &lt;a href=&quot;https://twitter.com/edwinbrady&quot;&gt;@edwinbrady&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/KatsConf2?src=hash&quot;&gt;#KatsConf2&lt;/a&gt;  &lt;a href=&quot;https://t.co/KpzHhzXxMX&quot;&gt;https://t.co/KpzHhzXxMX&lt;/a&gt;&lt;/p&gt;&amp;mdash; Jessica Kerr (@jessitron) &lt;a href=&quot;https://twitter.com/jessitron/status/833021344182915074&quot;&gt;February 18, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;a href=&quot;http://www.idris-lang.org/&quot;&gt;Idris&lt;/a&gt; is a pure functional language with dependent types. It’s a “total” language, which means you have program totality: a program either terminates, or gives you new results.&lt;/p&gt;

&lt;p&gt;Goals are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Encourage type-driven development&lt;/li&gt;
  &lt;li&gt;Reduce the cost of writing correct software - giving you more tools to know upfront the program will do the correct thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;People on the internet say, you can’t do X, you can’t do Y in a total language. I’m going to do X and Y in a total language.&lt;/p&gt;

&lt;p&gt;Types become plans for a program. Define the type up front, and use it to guide writing the program.&lt;/p&gt;

&lt;p&gt;You define the program interactively. The compiler should be less like a teacher, and more like a lab assistant. You say “let’s work on this” and it says “yes! let me help you”.&lt;/p&gt;

&lt;p&gt;As you go, you need to refine the type and the program as necessary.&lt;/p&gt;

&lt;p&gt;Test-driven development has “red, green, refactor”. We have “type, define, refine”.&lt;/p&gt;

&lt;p&gt;If you care about types, you should also care about totality. You don’t have a type that completely describes your program unless your program is total.&lt;/p&gt;

&lt;p&gt;Given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f : T&lt;/code&gt;: if program &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; is total, we know that it will always give a result of type T. If it’s partial, we only know that &lt;em&gt;if&lt;/em&gt; it gives a result, it will be type T, but it might crash, run forever, etc. and not give a result.&lt;/p&gt;

&lt;p&gt;The difference between total and partial functions in this world: if it’s total, we can think of it as a Theorem.&lt;/p&gt;

&lt;p&gt;Idris can tell us whether or not it thinks a program is total (though we can’t be sure, because we haven’t solved the halting problem “yet”, as a student once wrote in an assignment). If I write a program that type checks but Idris thinks it’s possibly not total, then I’ve probably done the wrong thing. So in my Idris code I can tell it that some function I’m defining should be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;total&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I can also tell Idris that if I can prove something that’s impossible, then I can basically deduce anything, e.g. an alt-fact about arithmetic. We have the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;absurd&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;We have Streams, where a Stream is sort of like a list without &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nil&lt;/code&gt;, so potentially infinite. As far as the runtime is concerned, this means this is lazy. Even though we have strictness.&lt;/p&gt;

&lt;p&gt;Idris uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IO&lt;/code&gt; like Haskell to write interactive programs. IO is a description of actions that we expect the program to make(?). If you want to write interactive programs that loop, this stops it being total. But we can solve this by describing looping programs as a stream of IO actions. We know that the potentially-infinite loops are only going to get evaluated when we have a bit more information about what the program is going to do.&lt;/p&gt;

&lt;p&gt;Turns out, you can use this to write servers, which run forever and accept responses, which are total. (So the people on the internet are wrong).&lt;/p&gt;

&lt;p&gt;Check out David Turner’s paper “Elementary Strong Functional Programming”, where he argues that totality is more important than Turing-completeness, so if you have to give up one you should give up the latter.&lt;/p&gt;

&lt;p&gt;Book coming out: &lt;a href=&quot;https://www.tinyurl.com/typedd&quot;&gt;Type-Driven Development with Idris&lt;/a&gt;&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">Hello from Dublin! Yesterday I had the privilege of attending KatsConf2, a functional programming conference put on by the fun-loving, welcoming, and crazy-well-organized @FunctionalKats. It was a whirlwind of really exciting talks from some of the best speakers around. Here’s a glimpse into what I learned.</summary></entry><entry><title type="html">Notes from FOSDEM 2017</title><link href="http://anjana.dev/blog/fosdem-2017/" rel="alternate" type="text/html" title="Notes from FOSDEM 2017" /><published>2017-02-13T00:00:00+00:00</published><updated>2017-02-13T00:00:00+00:00</updated><id>http://anjana.dev/blog/fosdem-2017</id><content type="html" xml:base="http://anjana.dev/blog/fosdem-2017/">&lt;p&gt;Riding the tram you hear the word “Linux” pronounced in four different languages. Stepping out into the grey drizzle, you instantly smell fresh waffles and GitHub-sponsored coffee, and everywhere you look you see a &lt;a href=&quot;http://www.fsf.org/&quot;&gt;FSF&lt;/a&gt; t-shirt. That’s right kids, it’s &lt;a href=&quot;https://fosdem.org/2017/&quot;&gt;FOSDEM&lt;/a&gt; time again! The beer may not be free, but the software sure is.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/blog/fosdem-2016/&quot;&gt;Last year&lt;/a&gt; I got my first taste of this most epic of FLOSS conferences, back when I was an unemployed ex-grad-student with not even 5 pull requests to my name. This year, as a bona fide open source contributor, Mozillian, and full-time professional software engineer, I came back for more. Here are some things I learned:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Open source in general - and, anecdotally, FOSDEM in particular - has a &lt;a href=&quot;#diversity&quot;&gt;diversity&lt;/a&gt; problem. (Yes, we already knew this, but it still needs mentioning.)&lt;/li&gt;
  &lt;li&gt;…But not for long, if organizations like &lt;a href=&quot;#mozilla&quot;&gt;Mozilla&lt;/a&gt; and projects like &lt;a href=&quot;#includo&quot;&gt;IncLudo&lt;/a&gt; have anything to say about it.&lt;/li&gt;
  &lt;li&gt;Games are a powerful tool to &lt;a href=&quot;#invaders&quot;&gt;introduce programming&lt;/a&gt;, &lt;a href=&quot;#includo&quot;&gt;promote diversity&lt;/a&gt;, and build &lt;a href=&quot;#hellink&quot;&gt;21st-century&lt;/a&gt; &lt;a href=&quot;#tablexia&quot;&gt;literacy&lt;/a&gt; skills.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#speech&quot;&gt;Speech&lt;/a&gt; applications built on open technologies are not just a pipe dream!&lt;/li&gt;
  &lt;li&gt;How browsers &lt;a href=&quot;#webrender&quot;&gt;render the web&lt;/a&gt; is super interesting and something I want to get a clue about.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#foxpuppet&quot;&gt;FoxPuppet&lt;/a&gt; is making automating &amp;amp; testing Firefox even easier than with our beloved Marionette!&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://twitter.com/mozTechSpeakers&quot;&gt;Mozilla Tech Speakers&lt;/a&gt; are straight killin’ it.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;— &amp;quot;How do you say “&lt;a href=&quot;https://twitter.com/mozTechSpeakers&quot;&gt;@mozTechSpeakers&lt;/a&gt; rocked &lt;a href=&quot;https://twitter.com/fosdem&quot;&gt;@FOSDEM&lt;/a&gt; today!” in fox?&lt;br /&gt;— … 😉&lt;a href=&quot;https://twitter.com/hashtag/mozdem?src=hash&quot;&gt;#mozdem&lt;/a&gt; &lt;a href=&quot;https://t.co/KStl9R8QLM&quot;&gt;pic.twitter.com/KStl9R8QLM&lt;/a&gt;&lt;/p&gt;&amp;mdash; Flaki (@slsoftworks) &lt;a href=&quot;https://twitter.com/slsoftworks/status/827951076586438657&quot;&gt;February 4, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Open data for bike sharing programs in &amp;gt;400 cities around the world! 💚🚲💚 &lt;a href=&quot;https://t.co/liu6MOI8Nc&quot;&gt;https://t.co/liu6MOI8Nc&lt;/a&gt; &lt;a href=&quot;https://twitter.com/ctbikes&quot;&gt;@ctbikes&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/FOSDEM?src=hash&quot;&gt;#FOSDEM&lt;/a&gt; &lt;a href=&quot;https://t.co/QHJyx3QzAm&quot;&gt;pic.twitter.com/QHJyx3QzAm&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/828247891877715972&quot;&gt;February 5, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Wrapped up the day with some VR painting in the browser (!!!) at the &lt;a href=&quot;https://twitter.com/mozilla&quot;&gt;@mozilla&lt;/a&gt; stand - see you next year &lt;a href=&quot;https://twitter.com/hashtag/FOSDEM?src=hash&quot;&gt;#FOSDEM&lt;/a&gt; ✌️ &lt;a href=&quot;https://t.co/d23v7sRY9a&quot;&gt;pic.twitter.com/d23v7sRY9a&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/828276764208201730&quot;&gt;February 5, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;See the notes below for more!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: The (unedited!!!) notes below represent my impressions of the content of these talks, jotted down as I listened. They may or may not be totally accurate, or precisely/adequately represent what the speakers said or think. If you want to get it from the horse’s mouth, follow the links to the &lt;a href=&quot;https://fosdem.org/2017/schedule/&quot;&gt;FOSDEM schedule&lt;/a&gt; entry to find the video, slides, and/or other resources!&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;mozilla-dev-room-saturday&quot;&gt;&lt;a name=&quot;mozilla&quot;&gt;&lt;/a&gt;Mozilla Dev Room, Saturday&lt;/h2&gt;

&lt;h3 id=&quot;firefox-nightly&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_rebooting_firefox_nightly/&quot;&gt;Firefox Nightly&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Pascal Chevrel&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Nightly users are crucial for early detection of regressions and bugs introduced by new features (especially important with the advent of Quantum)&lt;/li&gt;
  &lt;li&gt;Nightly users aren’t as diverse as stable users:
    &lt;ul&gt;
      &lt;li&gt;86% Windows, 6% Linux, 5% Mac&lt;/li&gt;
      &lt;li&gt;Around 70% come from just 15 countries (USA, Germany, Russia at top)&lt;/li&gt;
      &lt;li&gt;Over 80% are using en-US locale&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Generally, Nightly users are tech-savvy (though not necessarily devs) - this means the bugs they report are generally higher-quality, more helpful&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Nightly Reboot Status: Project started in 2016 to encourage Nightly use and bring better integration with release process
    &lt;ul&gt;
      &lt;li&gt;Download pages: now you can download Nightly! :D&lt;/li&gt;
      &lt;li&gt;Nightly-specific default bookmarks&lt;/li&gt;
      &lt;li&gt;Locale-specific about:home page with e.g. info about local events, links to translated articles&lt;/li&gt;
      &lt;li&gt;Nightly IRC channel&lt;/li&gt;
      &lt;li&gt;Nightly blog (e.g. mconley’s “These weeks in Firefox”)&lt;/li&gt;
      &lt;li&gt;@FirefoxNightly on Twitter&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Help out!
    &lt;ul&gt;
      &lt;li&gt;Use Nightly as your main browser&lt;/li&gt;
      &lt;li&gt;Translate information &amp;amp; help bug reporters that aren’t comfortable with English&lt;/li&gt;
      &lt;li&gt;Help triage bugs - too many for Mozilla staff to handle&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q&amp;amp;A
    &lt;ul&gt;
      &lt;li&gt;A lot of former Nightly users have moved over to Aurora - this means they find the bugs later, and Aurora isn’t more stable/as stable as people expect&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;firefox-devtools&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_devtools_deep_dive/&quot;&gt;Firefox DevTools&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Alex “Laka” Lakatos (@lakatos88)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Opening DevTools:
    &lt;ul&gt;
      &lt;li&gt;Right click &amp;gt; Inspect Element&lt;/li&gt;
      &lt;li&gt;Tools menu&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Element inspector:
    &lt;ul&gt;
      &lt;li&gt;Search box: can search for CSS selectors&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;CSS rules:
    &lt;ul&gt;
      &lt;li&gt;use filter box to find e.g. every ‘color’ selector&lt;/li&gt;
      &lt;li&gt;Colors
        &lt;ul&gt;
          &lt;li&gt;Shift-Click on colored circle to switch between hex/RGB/named representation&lt;/li&gt;
          &lt;li&gt;Click on it to get color picker&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Debugger
    &lt;ul&gt;
      &lt;li&gt;Click line to set breakpoint&lt;/li&gt;
      &lt;li&gt;Can view all variables at the point where execution is paused&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Network
    &lt;ul&gt;
      &lt;li&gt;Shows every request you make&lt;/li&gt;
      &lt;li&gt;Shows two sizes: Size during transport and size on disk - helps you minimize transfer time&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;DevTools in Nightly
    &lt;ul&gt;
      &lt;li&gt;New features rolled out constantly&lt;/li&gt;
      &lt;li&gt;Disable HTTP Cache when DevTools is open - super useful while you’re developing and the cache drives you insane!&lt;/li&gt;
      &lt;li&gt;If you’re nostalgic, can use the Firebug theme&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Moving DevTools to add-on instead of built in to Firefox - Will help ship faster&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;webextensions&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_firefox_and_webextensions/&quot;&gt;WebExtensions&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Daniele Scasciafratte&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Firefox is famous for extensions - it’s the most customizable browser out there&lt;/li&gt;
  &lt;li&gt;Extensions sometimes become features of Ffx itself&lt;/li&gt;
  &lt;li&gt;WebExtensions is “One API to Rule Them All”
    &lt;ul&gt;
      &lt;li&gt;Standard HTML/CSS/JS (not XUL)&lt;/li&gt;
      &lt;li&gt;compatibility with Chrome&lt;/li&gt;
      &lt;li&gt;Content scripts allow extensions to run in pages&lt;/li&gt;
      &lt;li&gt;Background scripts allow them to maintain long-term state from the moment they’re installed to the moment they’re removed&lt;/li&gt;
      &lt;li&gt;Fully customizable “browser actions” (buttons on top right) with their own menus etc.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-firefox-puppet-show&quot;&gt;&lt;a name=&quot;foxpuppet&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_firefox_puppet_show/&quot;&gt;The Firefox Puppet Show&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Dave Hunt (&amp;amp; Henrik the Foxy Puppet)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Selenium
    &lt;ul&gt;
      &lt;li&gt;Tool for browser automation&lt;/li&gt;
      &lt;li&gt;Never maintained by Mozilla&lt;/li&gt;
      &lt;li&gt;Works for multiple browsers, including Firefox&lt;/li&gt;
      &lt;li&gt;Limited to the content space; has no control over browser chrome&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;FirefoxDriver
    &lt;ul&gt;
      &lt;li&gt;Deprecated due to add-on signing from Ffx 48&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Marionette (Woo!!!)
    &lt;ul&gt;
      &lt;li&gt;Introduced 2012, originally for FirefoxOS&lt;/li&gt;
      &lt;li&gt;Directly integrated into Gecko&lt;/li&gt;
      &lt;li&gt;Controls chrome and content (whereas Selenium is content-based)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;GeckoDriver
    &lt;ul&gt;
      &lt;li&gt;Proxy for W3C WebDriver &amp;amp; Gecko&lt;/li&gt;
      &lt;li&gt;WebDriver spec should be a recommendation by end of Q1 2017&lt;/li&gt;
      &lt;li&gt;Idea: any browser implementing the spec can be automated&lt;/li&gt;
      &lt;li&gt;Has been adopted by all major browser vendors&lt;/li&gt;
      &lt;li&gt;Thanks to WebDriver, Selenium (or any automation client) doesn’t have to worry about how to automate all the browsers: just has to implement the spec, and can then control any compliant browser&lt;/li&gt;
      &lt;li&gt;GeckoDriver not feature complete yet, partly bc the spec is still in late stages of development&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;FoxPuppet
    &lt;ul&gt;
      &lt;li&gt;Python package w/ simple API for finding &amp;amp; interacting with the Firefox UI&lt;/li&gt;
      &lt;li&gt;Allows you to interact with Firefox in Selenium, builds on top of Selenium&lt;/li&gt;
      &lt;li&gt;Ultimately going to be used to test Ffx itself&lt;/li&gt;
      &lt;li&gt;Marionette can do more than what just Selenium offers (chrome); FoxPuppet takes it the next step by making it much simpler to write automation code using Selenium+Marionette&lt;/li&gt;
      &lt;li&gt;At the moment supports window management, interaction with popups, soon interaction with tabs…&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Excited about FoxPuppet @ &lt;a href=&quot;https://twitter.com/hashtag/mozdem?src=hash&quot;&gt;#mozdem&lt;/a&gt;! It&amp;#39;s even easier to automate &amp;amp; test &lt;a href=&quot;https://twitter.com/firefox&quot;&gt;@Firefox&lt;/a&gt; now: &lt;a href=&quot;https://t.co/apmdCW3ZMC&quot;&gt;https://t.co/apmdCW3ZMC&lt;/a&gt; &lt;a href=&quot;https://twitter.com/davehunt82&quot;&gt;@davehunt82&lt;/a&gt; &lt;a href=&quot;https://twitter.com/whimboo&quot;&gt;@whimboo&lt;/a&gt; &lt;a href=&quot;https://t.co/RRnJoE49sO&quot;&gt;pic.twitter.com/RRnJoE49sO&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/827849820626882560&quot;&gt;February 4, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;Q&amp;amp;A:
    &lt;ul&gt;
      &lt;li&gt;Can it run headlessly?
        &lt;ul&gt;
          &lt;li&gt;No, because there’s no true headless mode for Firefox, though you can make it effectively headless via e.g. running in Docker&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Can it work with WebGL?
        &lt;ul&gt;
          &lt;li&gt;The problem is similar to with canvas - if we just have one element, we can’t look inside of it unless there’s some workaround to expose additional information about the the state of the app specifically for testing&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Excecuting async JS?
        &lt;ul&gt;
          &lt;li&gt;Selenium has functionality to handle this, and since FoxPuppet builds on Selenium, the base Selenium functionality is still available&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;webrender&quot;&gt;&lt;a name=&quot;webrender&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_webrender_next_generation_graphics_engine/&quot;&gt;WebRender&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Nicolas Silva&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Servo
    &lt;ul&gt;
      &lt;li&gt;Mostly research, for trying out new ideas more quickly than we could in Ffx (without worrying about putting it in front of users)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;How do rendering engines work? (Using Gecko as a reference)
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;layout&lt;/em&gt;: DOM Tree layout is computed and transformed into a Frame Tree (has other names in e.g. WebKit)&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;invalidation&lt;/em&gt;: From the Frame Tree we get a display list - pretty flat structure of things we need to render&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;painting&lt;/em&gt;: We then render the display list into a Layer Tree
        &lt;ul&gt;
          &lt;li&gt;like layers in Photoshop&lt;/li&gt;
          &lt;li&gt;Intermediate surfaces containing rendered elements&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;em&gt;compositing&lt;/em&gt;: mirror the layer tree on the compositor process, for scrolling etc. at a high frame rate&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;WebRender
    &lt;ul&gt;
      &lt;li&gt;attempts to move away from this type of architecture and do something different&lt;/li&gt;
      &lt;li&gt;designed to work around the GPU, like a game rendering engine&lt;/li&gt;
      &lt;li&gt;drops the distinction between painting/compositing, and just render everything to the window directly&lt;/li&gt;
      &lt;li&gt;take the page content &amp;amp; turn it into a series of primitives we can send to the GPU (??)&lt;/li&gt;
      &lt;li&gt;written in Rust&lt;/li&gt;
      &lt;li&gt;using OpenGL for now, though in the future other backends would be possible&lt;/li&gt;
      &lt;li&gt;doesn’t understand arbitrary shapes, but rather only a simple set of shapes that are common on the web (e.g. rectangles, rounded rects)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Working fast on a GPU
    &lt;ul&gt;
      &lt;li&gt;GPUs are very stateful things, so switching state/state changes have a big impact&lt;/li&gt;
      &lt;li&gt;Batching is the key&lt;/li&gt;
      &lt;li&gt;Transferring data to/from the CPU is expensive&lt;/li&gt;
      &lt;li&gt;Memory bandwidth is really costly, especially on mobile devices - so try to avoid touching too many pixels/touching the same pixels too many times (aka “overdraw”)
        &lt;ul&gt;
          &lt;li&gt;Rendering back-to-front, you have to draw e.g. the whole background even if most of it is covered by other things&lt;/li&gt;
          &lt;li&gt;Rendering front-to-back means you can avoid drawing any parts of layers other than those that will ultimately be seen&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;how-rust-is-being-developed&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_rust_development/&quot;&gt;How Rust is being developed&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;@jgbarah Jesus M. Gonzalez-Barahona, Bitergia&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Analytics dashboard with contribution data: https://rust-analytics.mozilla.community&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;code-invaders-learning-to-code-with-iot-games-and-htmlcssjs&quot;&gt;&lt;a name=&quot;invaders&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_iot_coding_with_html5_games/&quot;&gt;Code Invaders: Learning to code with IoT games and HTML/CSS/JS&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;István “Flaki” Szmozsánszky @slsoftworks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Happy Code Friends
    &lt;ul&gt;
      &lt;li&gt;Tech needs more diversity, we need more people to learn to code&lt;/li&gt;
      &lt;li&gt;But we need to spark people’s interest - games!&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Arduboy
    &lt;ul&gt;
      &lt;li&gt;Kickstarter project funded about 1-2 years ago&lt;/li&gt;
      &lt;li&gt;Basically puts a micro Arduino, screen, buttons in a nice little (cheap) package&lt;/li&gt;
      &lt;li&gt;But unfortunately you had to write programs for it in C through the Arduino IDE - not very beginner friendly&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Code Invaders
    &lt;ul&gt;
      &lt;li&gt;Teaching people the basics of programming (functions, variables, …) while building their own game&lt;/li&gt;
      &lt;li&gt;Code is written in JS and compiled to C by pushing a button in the IDE&lt;/li&gt;
      &lt;li&gt;Makes Arduboy programming accessible for beginners&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&lt;a href=&quot;https://twitter.com/slsoftworks&quot;&gt;@slsoftworks&lt;/a&gt; invaded spaces at &lt;a href=&quot;https://twitter.com/hashtag/mozdem?src=hash&quot;&gt;#mozdem&lt;/a&gt;, showing us how beginners can learn to code &lt;a href=&quot;https://twitter.com/hashtag/arduboy?src=hash&quot;&gt;#arduboy&lt;/a&gt; games in JS! &lt;a href=&quot;https://t.co/WKNrGUpAvv&quot;&gt;pic.twitter.com/WKNrGUpAvv&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/827886909372379136&quot;&gt;February 4, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;h3 id=&quot;diversity-in-open-source&quot;&gt;&lt;a name=&quot;diversity&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_diversity_user_research/&quot;&gt;Diversity in Open Source&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Kristi Pogri @KristiPogri&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Hard truths about (lack of) diversity in FOSS as &lt;a href=&quot;https://twitter.com/mozTechSpeakers&quot;&gt;@mozTechSpeakers&lt;/a&gt; own &lt;a href=&quot;https://twitter.com/KristiProgri&quot;&gt;@KristiProgri&lt;/a&gt; opens eyes at &lt;a href=&quot;https://twitter.com/hashtag/mozdem?src=hash&quot;&gt;#mozdem&lt;/a&gt; &lt;a href=&quot;https://t.co/VzAZEofTQT&quot;&gt;pic.twitter.com/VzAZEofTQT&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/827926761694441472&quot;&gt;February 4, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;Horrendenously low %s of open-source developers are women&lt;/li&gt;
  &lt;li&gt;Open source isn’t really open unless it’s open to everyone&lt;/li&gt;
  &lt;li&gt;Organizations/initiatives like WoMoz and Outreachy are actively trying to change this&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;diversity-user-research&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_diversity_user_research/&quot;&gt;Diversity user research&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Gloria Dwomoh&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Listening is a skill, one which we don’t study enough in comparison with e.g. reading, writing, speaking&lt;/li&gt;
  &lt;li&gt;Hearing vs. Listening:
    &lt;ul&gt;
      &lt;li&gt;Hearing is perceiving sounds&lt;/li&gt;
      &lt;li&gt;Listening is concentrating on them&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Body language is important for listening - showing that you’re bored makes the speaker cut themselves off&lt;/li&gt;
  &lt;li&gt;Active listening
    &lt;ul&gt;
      &lt;li&gt;Reflection: when someone tells you something, you try to reflect back what they’re saying - to show that you understood, e.g. “so you mean that….”&lt;/li&gt;
      &lt;li&gt;Funneling: you try to ask for more general or more specific information&lt;/li&gt;
      &lt;li&gt;Empathy: important for building trust with the speaker
        &lt;ul&gt;
          &lt;li&gt;Sympathy is “oh, that must have been hard, I’m sorry”&lt;/li&gt;
          &lt;li&gt;Empathy is also “I understand what you mean, because I had a similar experience when ….” - show that you deeply understand the speaker’s experience&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Active listening: reflect, summarize, clarify, show empathy. &lt;a href=&quot;https://twitter.com/mozTechSpeakers&quot;&gt;@mozTechSpeakers&lt;/a&gt; own Gloria Dwomoh reminds us we should all get better at this &lt;a href=&quot;https://t.co/UzemrL5YZ1&quot;&gt;pic.twitter.com/UzemrL5YZ1&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/827930991373201408&quot;&gt;February 4, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;h3 id=&quot;dont-break-the-internet-mozilla-copyright-campaign-in-europe&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/mozilla_copyright_campaign_europe/&quot;&gt;Don’t break the internet! Mozilla Copyright Campaign in Europe&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Raegan MacDonald&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We need to bring copyright into the 21st century
    &lt;ul&gt;
      &lt;li&gt;Bring in flexibility&lt;/li&gt;
      &lt;li&gt;Encourage creativity &amp;amp; expression online&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Copyright reform is happening, but unfortunately it’s not the kind of reform we need
    &lt;ul&gt;
      &lt;li&gt;Doesn’t focus on the interests of users on the internet&lt;/li&gt;
      &lt;li&gt;Instead of protecting &amp;amp; encouraging innovation &amp;amp; creativity online, may in some cases undermine that&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Mozilla wants to ensure that the internet remains a “global public resource open &amp;amp; accessible to all”
    &lt;ul&gt;
      &lt;li&gt;not trying to get rid of copyright&lt;/li&gt;
      &lt;li&gt;but rather encourage copyright laws that support all actors in the web ecosystem&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Issues in the current copyright directive
    &lt;ul&gt;
      &lt;li&gt;Upload filters:
        &lt;ul&gt;
          &lt;li&gt;platforms that are holding large amounts of copyrighted content would need agrements with rights holders&lt;/li&gt;
          &lt;li&gt;ensuring that they uphold those agreements would require them to implement upload filters that may end up restricting users’ ability to post their own content&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Neighboring rights - aka “snippet tax” or “google tax”
        &lt;ul&gt;
          &lt;li&gt;proposal to extend copyright to press publishers&lt;/li&gt;
          &lt;li&gt;press publications would get to charge aggregators for e.g. posting a snippet of their article, the headline, and a hyperlink&lt;/li&gt;
          &lt;li&gt;already been attempted in Germany and Spain, where it had negative effects on startup aggregators and entrenched the power of established aggregators (Google)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Text &amp;amp; Data Mining (TDM)
        &lt;ul&gt;
          &lt;li&gt;there would be restrictions on ingesting copyrighted data for the purposes of data mining&lt;/li&gt;
          &lt;li&gt;there would only be exceptions for research institutions&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The fight right now is unfortunately quite binary: The big Silicon Valley companies/aggregators (Google etc.) vs. the Publishing/Music/Film industry
    &lt;ul&gt;
      &lt;li&gt;We need it to involve the full spectrum of stakeholders on the web, especially users, independent content creators&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Get involved!
    &lt;ul&gt;
      &lt;li&gt;changecopyright.org&lt;/li&gt;
      &lt;li&gt;raegan@mozilla.com&lt;/li&gt;
      &lt;li&gt;Series of events across Europe&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q&amp;amp;A:
    &lt;ul&gt;
      &lt;li&gt;Since filtering requires monitoring, and monitoring is unconstitutional in the EU, are there plans to fight this if it passes?
        &lt;ul&gt;
          &lt;li&gt;Yes, there is absolutely a contradiction there, and we plan to fight it. We want to bring the proposal in line with existing law and channel activism against these filters.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Previous events/campaigns were focused on Freedom of Panorama (copyright exception that allows you to take photographs of e.g. buildings, art and post them online). Will new events be focused on the 4 areas you discussed?
        &lt;ul&gt;
          &lt;li&gt;Yes, this is sort of our 2nd wave of activism on this issue, and we’ll be organizing and encouraging more advocacy around these issues.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Do you coordinate with the media?
        &lt;ul&gt;
          &lt;li&gt;Yes. There are a number of organizations working on a modern version of copyright that looks forward, not backwards. The C4C (copyright for creativity) brings together a lot of players (e.g libraries, digital rights NGOs), and that serves as a sort of umbrella. A lot of folks have similar issues and we work together as much as possible to amplify &amp;amp; support certain voices.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;What is the purpose of another wave? Are we starting over?
        &lt;ul&gt;
          &lt;li&gt;EU policy making is a very slow game. This reform has been under discussion for over 5 years, and the process of it going through negotiations to reach a final EU parliament agreement will be at least a year. If we want to have an impact &amp;amp; mobilize different voices, it has to be a sustained, long-term effort, which was not the case in the 1st wave because we didn’t have the proposal yet. Now that we have it, we have more focus on what to encourage people to speak out about, which is potentially game-changing.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;It seems that the education exception excludes all informal sources of education
        &lt;ul&gt;
          &lt;li&gt;This exception applies to cases where licensed materials can’t be acquired. But that’s not really the problem; the problem is the cost. There’s now a campaign copyrightforeducation.org. It’s something we’re following closely, and we’re mostly relying on our partners who are experts in this area.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;When will this be decided by parliament?
        &lt;ul&gt;
          &lt;li&gt;There will be votes on committee opinions next month, but the main opinion will be deliberated in March, and they want it to be voted by end of summer 2017. So the next 6 months could be game-changing, it’s an important time to contact your representatives.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Would the TDM exception implicate privacy concerns?
        &lt;ul&gt;
          &lt;li&gt;This doesn’t deal with privacy-protected content, but rather would allow people that have lawfully acquired works/texts to create e.g. a visualization. It doesn’t get into privacy issues about mining people’s metadata and all that - it’s a separate issue from privacy and wouldn’t override it.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;other-rooms-saturday-sunday&quot;&gt;Other rooms, Saturday-Sunday&lt;/h2&gt;

&lt;h3 id=&quot;webrtc-and-speech-recognition-with-adhearsion&quot;&gt;&lt;a name=&quot;speech&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/webrtc_speech_recognition/&quot;&gt;WebRTC and speech recognition with Adhearsion&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Luca Pradovera @lucaprado -  MojoLingo&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Spoken dialog system built entirely on open tools&lt;/li&gt;
  &lt;li&gt;PocketSphinx for recognition (understands stock grammar of ~100 words)&lt;/li&gt;
  &lt;li&gt;Rasa NLU for interpretation&lt;/li&gt;
  &lt;li&gt;Flite for TTS (voice a bit robotic but gets the job done)&lt;/li&gt;
  &lt;li&gt;FreeSwitch - switching platform with good WebRTC support. Asterisk is an alternative&lt;/li&gt;
  &lt;li&gt;Adhearsion is the main control layer
    &lt;ul&gt;
      &lt;li&gt;Ruby framework for voice apps&lt;/li&gt;
      &lt;li&gt;handles things like picking up the call, transferring, answering, recording, etc.&lt;/li&gt;
      &lt;li&gt;Connects to FreeSwitch or Asterisk&lt;/li&gt;
      &lt;li&gt;Uses actor model - treats each call as an actor, handles it in isolation (so if one call fails, the whole system doesn’t fail)&lt;/li&gt;
      &lt;li&gt;Case studies
        &lt;ul&gt;
          &lt;li&gt;RingRx HIPAA-compliant phone system&lt;/li&gt;
          &lt;li&gt;LiveConnect for broadcasting surgical procedures&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;can-open-source-open-minds-includo-games-for-workplace-diversity&quot;&gt;&lt;a name=&quot;includo&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/ogd_includo/&quot;&gt;Can open source open minds? IncLudo games for workplace diversity&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Jesse Himmelstein&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;&amp;quot;Diversity is an institutional advantage.&amp;quot; WORD. &lt;a href=&quot;https://twitter.com/himmelattack&quot;&gt;@himmelattack&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://twitter.com/IncludoProject&quot;&gt;@IncludoProject&lt;/a&gt; are trying to ++ workplace diversity with games 🤘 &lt;a href=&quot;https://twitter.com/hashtag/FOSDEM?src=hash&quot;&gt;#FOSDEM&lt;/a&gt; &lt;a href=&quot;https://t.co/ynqIgnxoKq&quot;&gt;pic.twitter.com/ynqIgnxoKq&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/828218342712410112&quot;&gt;February 5, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;Diversity is an institutional advantage&lt;/li&gt;
  &lt;li&gt;But it’s difficult to implement - “we are feeling beings who think, not thinking beings who feel”
    &lt;ul&gt;
      &lt;li&gt;some research suggests that our ability to reason may exist to convince others of our ideas, rather than to make decisions&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;IncLudo project created a variety of games to improve workplace diversity in India
    &lt;ul&gt;
      &lt;li&gt;some teach about biases&lt;/li&gt;
      &lt;li&gt;some (esp. board games) encourage conversation &amp;amp; exchange of experiences/stories among players&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Process
    &lt;ul&gt;
      &lt;li&gt;Game jams are a good way to try out new ideas&lt;/li&gt;
      &lt;li&gt;Paper prototypes are great for experimenting, though clients don’t always accept them so easily&lt;/li&gt;
      &lt;li&gt;Having a diverse team helps&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Q&amp;amp;A
    &lt;ul&gt;
      &lt;li&gt;You mentioned a game where you have to hide your bias from others
        &lt;ul&gt;
          &lt;li&gt;You pretend you’re management at a company, and you have to hire someone for a position. Everyone has a secret bias card (“don’t want to hire [women, muslims, …]”). Your goal is to fight for the candidate you (don’t) want, but without being so obvious about it as to reveal your secret bias to the other managers. There were some really funny conversations coming out of it.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;How do you measure the impact?
        &lt;ul&gt;
          &lt;li&gt;That’s really hard. There’s a few different things: you can try to measure what people learned from the game, which is difficult in itself. The other attempt is to see what the organizations actually do in real live - that’s what (our partner) ZMQ is going to do: see if the orgs actually change their practices.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;How do your games relate to competitive vs. collaborative games
        &lt;ul&gt;
          &lt;li&gt;I wouldn’t agree that competition is bad by itself - it motivates us and as long as we understand that we’re competing in the game and not once it’s over. Our games are competitive, with the exception of Pirat Partage which wasn’t competitive but then the players started asking us for a scoring system so that they could see who’s winnign&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Aren’t competition and diversity contradictory?
        &lt;ul&gt;
          &lt;li&gt;If you’re trying to bring diversity into an existing social structure made of companies that are competing, it makes sense to sell it to them that way.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;hellink-an-educational-game-about-open-data&quot;&gt;&lt;a name=&quot;hellink&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/ogd_hellink/&quot;&gt;Hellink, an educational game about open data&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Thomas Planques&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Game for 1st year uni students that aims to
    &lt;ul&gt;
      &lt;li&gt;teach information literacy:  critical thinking about info sources&lt;/li&gt;
      &lt;li&gt;raise awareness about open data&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;The game talks about process of creation of  scientific knowledge
    &lt;ul&gt;
      &lt;li&gt;Who pays for scientific knowledge?
        &lt;ul&gt;
          &lt;li&gt;Unis pay Scientists’ salaries&lt;/li&gt;
          &lt;li&gt;Unis must also pay publishers, the publishers don’t pay the scientists&lt;/li&gt;
          &lt;li&gt;Unis also pay to buy the journal, to buy back the knowledge&lt;/li&gt;
          &lt;li&gt;So we say in scientific knowledge domain, people (taxpayers) pay 3 times&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;What keeps this system going?
        &lt;ul&gt;
          &lt;li&gt;each scientist has an H index based on their publications that’s important for their career&lt;/li&gt;
          &lt;li&gt;the publishers own the journals, i.e. the means for scientists to advance their careers&lt;/li&gt;
          &lt;li&gt;monopoly by big scientific publishers make knowledge less accessible&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;One big solution would be the open data movement
        &lt;ul&gt;
          &lt;li&gt;publishing not in private journals, but open source archives&lt;/li&gt;
          &lt;li&gt;but scientists often think this will strip them of their work
            &lt;ul&gt;
              &lt;li&gt;but it’s the other way around&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;This is the subject of our game: we believe in the goal of open knowledge
        &lt;ul&gt;
          &lt;li&gt;the goal is to raise awareness about this problem&lt;/li&gt;
          &lt;li&gt;and also that checking the sources of your info is very important&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;We chose to use the same humorous tone as Ace Attorney (manga-like Japanese game where you play a lawyer, trial is like Dragonball-Z)
        &lt;ul&gt;
          &lt;li&gt;you’re sent to investigate a massive plot linked to who owns info &amp;amp; data in the uni/scientific publishing world&lt;/li&gt;
          &lt;li&gt;you have one person who tells you a false assertion backed by false info sources&lt;/li&gt;
          &lt;li&gt;like in Papers Please, you need to point out what is false in the info source &amp;amp; link it with a publishing rule that the source is supposed to respect&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;What we learned
        &lt;ul&gt;
          &lt;li&gt;procedural rhetoric: the game itself must convey the message
            &lt;ul&gt;
              &lt;li&gt;a lot of educational games involve a little playing and a lot of reading&lt;/li&gt;
              &lt;li&gt;the goal here is that you actually learn by playing&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;making a game about notions like this that have gray areas is a lot harder than making games about hard science/math/programming etc. &amp;amp; needs more time invested&lt;/li&gt;
          &lt;li&gt;what should ed games aim to do?
            &lt;ul&gt;
              &lt;li&gt;games in general are not very good at conveying a very complex message/complex domain of learning&lt;/li&gt;
              &lt;li&gt;what they’re good at is piquing interest and raising awareness&lt;/li&gt;
              &lt;li&gt;ed games shouldn’t aim to teach everything to the player, but rather to give them the interest to go look into the topic themselves&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;we tried to make our game one that’s actually fun in itself
            &lt;ul&gt;
              &lt;li&gt;the game is for 1st year uni students, who by that point are used to playing a lot of “serious games” that are not up to the standard of entertainment games&lt;/li&gt;
              &lt;li&gt;ours aims not just to be a “serious game” for education, but one that’s actually fun to play in and of itself&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;The game will be released (for free) in April 2017&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;tablexia-app-for-children-with-dyslexia&quot;&gt;&lt;a name=&quot;tablexia&quot;&gt;&lt;a href=&quot;https://fosdem.org/2017/schedule/event/ogd_tablexia/&quot;&gt;Tablexia: app for children with dyslexia&lt;/a&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Andrea Sichova, cz.nic&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cognitive training for children with dyslexia
    &lt;ul&gt;
      &lt;li&gt;focused on older children, 11-15 years&lt;/li&gt;
      &lt;li&gt;teachers told us: we can give a lot of lessons, but with older children the problem is motivation&lt;/li&gt;
      &lt;li&gt;so we developed a game to address that&lt;/li&gt;
      &lt;li&gt;available on Android/iOS&lt;/li&gt;
      &lt;li&gt;available in schools &amp;amp; counseling facilities, but we also encourage students to use it indepedently&lt;/li&gt;
      &lt;li&gt;Available in Czech, Slovak, and German language&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;What’s dyslexia?
    &lt;ul&gt;
      &lt;li&gt;specific learning disability&lt;/li&gt;
      &lt;li&gt;problems with reading/writing caused by cognitive functions (attention, working memory)&lt;/li&gt;
      &lt;li&gt;dyslexic people have different learning strategies to cope&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;App development
    &lt;ul&gt;
      &lt;li&gt;focused on mobile (Android)&lt;/li&gt;
      &lt;li&gt;testing: tried to put it in front of students as much as possible, ask questionnaires etc&lt;/li&gt;
      &lt;li&gt;difficulty: needs to be at the right level so that they’re neither bored nor frustrated&lt;/li&gt;
      &lt;li&gt;tasks:
        &lt;ul&gt;
          &lt;li&gt;attention/working memory: need to read instructions and remember how they relate to previous ones&lt;/li&gt;
          &lt;li&gt;spacial reasoning: map tiles&lt;/li&gt;
          &lt;li&gt;phonological recognition/analysis: see a word, hear different options, choose the right one&lt;/li&gt;
          &lt;li&gt;visual memory: have to click on the right things at the right time&lt;/li&gt;
          &lt;li&gt;visual recognition: recognizing “alien” writing symbols, some of which are similar to others&lt;/li&gt;
          &lt;li&gt;phonological memory: remember the content/order of sounds you heard&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;also includes “badges” for completing exercises, statistics view of progress, and “encyclopedia” with info about dyslexia (which also has voice recordings of all texts)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Does it work?
    &lt;ul&gt;
      &lt;li&gt;studying it is difficult: we need a lot of children diagnosed with dyslexia, and let them play the game for some time&lt;/li&gt;
      &lt;li&gt;children are not going to school regularly - problems with attendance&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Language
    &lt;ul&gt;
      &lt;li&gt;We focused on Czech&lt;/li&gt;
      &lt;li&gt;Dyslexia is closely related to the language
        &lt;ul&gt;
          &lt;li&gt;aspects that dyslexic children struggle with are different from e.g. Czech to German&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">Riding the tram you hear the word “Linux” pronounced in four different languages. Stepping out into the grey drizzle, you instantly smell fresh waffles and GitHub-sponsored coffee, and everywhere you look you see a FSF t-shirt. That’s right kids, it’s FOSDEM time again! The beer may not be free, but the software sure is.</summary></entry><entry><title type="html">Marionette, Act II: Harnessing automation to test the browser</title><link href="http://anjana.dev/blog/marionette-act-ii-testing/" rel="alternate" type="text/html" title="Marionette, Act II: Harnessing automation to test the browser" /><published>2016-08-22T00:00:00+00:00</published><updated>2016-08-22T00:00:00+00:00</updated><id>http://anjana.dev/blog/marionette-act-ii-testing</id><content type="html" xml:base="http://anjana.dev/blog/marionette-act-ii-testing/">&lt;p&gt;Welcome back to my post series on the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt; project! In &lt;a href=&quot;/blog/marionette-act-i-automation/&quot;&gt;Act I&lt;/a&gt;, we looked into Marionette’s automation framework for Gecko, the engine behind the Firefox browser. Here in Act II, we’ll take a look at a complementary side of the Marionette project: the testing framework that helps us run tests using our Marionette-animated browser, aka the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Marionette_Test_Runner&quot;&gt;Marionette test harness&lt;/a&gt;. If – like me at the start of my &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;Outreachy internship&lt;/a&gt; – you’re &lt;a href=&quot;https://en.wikipedia.org/wiki/Clueless_(film)&quot;&gt;clueless&lt;/a&gt; about test harnesses, or the Marionette harness in particular, and want to fix that, you’re in the right place!&lt;/p&gt;

&lt;!--/excerpt--&gt;

&lt;h2 id=&quot;wait-whats-marionette-again&quot;&gt;Wait, what’s Marionette again?&lt;/h2&gt;

&lt;p&gt;Quick recap from &lt;a href=&quot;/blog/marionette-act-i-automation/&quot;&gt;Act I&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt; refers to a suite of tools for automated testing of Mozilla browsers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In that post, we &lt;a href=&quot;/blog/marionette-act-i-automation/#how-do-marionettes-server-and-client-automate-the-browser&quot;&gt;saw&lt;/a&gt; how the Marionette automation framework lets us control the Gecko browser engine (our “puppet”), thanks to a &lt;em&gt;server&lt;/em&gt; component built into Gecko (the puppet’s “strings”) and a &lt;em&gt;client&lt;/em&gt; component (a “handle” for the puppeteer) that gives us a simple Python API to talk to the server and thus control the browser. But why do we need to automate the browser in the first place? What good does it do us?&lt;/p&gt;

&lt;p&gt;Well, one thing it’s great for is testing. Indulge me in a brief return to my puppet metaphor from last time, won’t you? If the &lt;em&gt;automation&lt;/em&gt; side of Marionette gives us strings and a handle that turn the browser into our puppet, the &lt;em&gt;testing&lt;/em&gt; side of Marionette gives that puppet a reason for being, by letting it perform: it sets up a stage for the puppet to dance on, tell it to carry out a given performance, write a review of that performance, and tear down the stage again.&lt;/p&gt;

&lt;p&gt;OK, OK, metaphor-indulgence over; let’s get real.&lt;/p&gt;

&lt;h2 id=&quot;wait-why-do-we-need-automated-browser-testing-again&quot;&gt;Wait, why do we need automated browser testing again?&lt;/h2&gt;

&lt;p&gt;As Firefox&lt;sup id=&quot;a1&quot;&gt;&lt;a href=&quot;#f1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; contributors, we don’t want to have to manually open up Firefox, click around, and check that everything works every time we change a line of code. We’re developers, we’re lazy!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://media4.popsugar-assets.com/files/thumbor/W4GOj04aYxDOfU2W8M8VooIy7A4/fit-in/1024x1024/filters:format_auto-!!-:strip_icc-!!-/2015/07/21/936/n/1922283/a3ec73cee2bf5525_1e96c7e2cf97ee07e043ac3cef331074/i/When-Your-Mom-Criticizes-Your-Strict-Diet-Quesadillas.gif&quot; alt=&quot;&amp;quot;Gosh, you say it like it's a bad thing&amp;quot; (GIF from the film &amp;quot;Clueless&amp;quot;)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;&lt;em&gt;Clueless&lt;/em&gt; via &lt;a href=&quot;http://www.popsugar.com/entertainment/Clueless-Movie-GIFs-37943154&quot;&gt;POPSUGAR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But we can’t &lt;em&gt;not&lt;/em&gt; do it, because then we might not realize that we’ve broken the entire internet (or, you know, introduced a bug that makes Firefox crash, which is just as bad).&lt;/p&gt;

&lt;p&gt;So instead of testing manually, we do the same thing we always do: make the computer do it for us!&lt;/p&gt;

&lt;p&gt;The type of program that can magically do this stuff for us is called a &lt;a href=&quot;https://en.wikipedia.org/wiki/Test_harness&quot;&gt;test harness&lt;/a&gt;. And there’s even a special version specific to testing Gecko-based browsers, called – can you guess? – the Marionette test harness, also known as the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Marionette_Test_Runner&quot;&gt;Marionette test runner&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(Lazy) Firefox contributors, rejoice!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.co/images/5e3ed62355b84ea1662a5fcc9178e85f/raw&quot; alt=&quot;&amp;quot;Two enthusiastic thumbs up!&amp;quot; (GIF from the film &amp;quot;Clueless&amp;quot;)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;&lt;em&gt;Clueless&lt;/em&gt; via &lt;a href=&quot;https://www.tenor.co/view/thumbsup-enthusiastic-clueless-gif-5146508&quot;&gt;tenor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, what exactly is this magical “test harness” thing? And what do we need to know about the Marionette-specific one?&lt;/p&gt;

&lt;h2 id=&quot;whats-a-test-harness&quot;&gt;What’s a test harness?&lt;/h2&gt;

&lt;p&gt;First of all, let’s not get hung up on the name “test harness” – the names people use to refer to these things can be a bit ambiguous and confusing, as we saw with other parts of the Marionette suite in Act I. So let’s set aside the name of the thing for now, and focus on what the thing does.&lt;/p&gt;

&lt;p&gt;Assuming we have a framework like the Marionette client/server that lets us automatically control the browser, the other thing we need for automatically testing the browser is something that lets us:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Properly set up &amp;amp; launch the browser, and any other related components we might need&lt;/li&gt;
  &lt;li&gt;Define tests we want to perform and their expected results&lt;/li&gt;
  &lt;li&gt;Discover tests defined in a file or directory&lt;/li&gt;
  &lt;li&gt;Run those tests, using the automation framework to do the stuff we want to do in the browser&lt;/li&gt;
  &lt;li&gt;Keep track of what we actually saw, and how it compares to what we expected to see&lt;/li&gt;
  &lt;li&gt;Report the results in human- and/or machine-readable logs&lt;/li&gt;
  &lt;li&gt;Clean up all of that stuff we set up in the beginning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Take out the browser-specific parts, and you’ve got the basic outline of what a test harness for any kind of software should do.&lt;/p&gt;

&lt;p&gt;Ever write tests using Python’s &lt;a href=&quot;https://docs.python.org/3/library/unittest.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt;&lt;/a&gt;, JavaScript’s &lt;a href=&quot;http://mochajs.org/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mocha&lt;/code&gt;&lt;/a&gt;, Java’s &lt;a href=&quot;http://junit.org&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JUnit&lt;/code&gt;&lt;/a&gt;, or a similar tool? If you’re like me, you might have been perfectly happy writing unit tests with one of these, thinking not:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Yeah, I know &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt;! It’s a test harness.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;but rather:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Yeah, I know &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt;! It’s, you know, a, like, thing for writing tests that lets you make assertions and write setup/teardown methods and stuff and, like, print out stuff about the test results, or whatever.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Turns out, they’re the same thing; one is just shorter (and less, like, full of “like”s, and stuff).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://media1.popsugar-assets.com/files/thumbor/cSwGkFRP96rFHR0GStr-CAC1m_4/fit-in/1024x1024/filters:format_auto-!!-:strip_icc-!!-/2015/07/21/936/n/1922283/f359498dff0704fd_Whatever-Clueless-GIF-1433983360/i/When-People-Tell-You-Going-Bed-9-pm-Lame.gif&quot; alt=&quot;&amp;quot;Whatever&amp;quot; (GIF from the film &amp;quot;Clueless&amp;quot;)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;&lt;em&gt;Clueless&lt;/em&gt; via &lt;a href=&quot;http://www.popsugar.com/entertainment/Clueless-Movie-GIFs-37943154&quot;&gt;POPSUGAR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So that’s the general idea of a test harness. But we’re not concerned with just any test harness; we want to know more about the &lt;em&gt;Marionette&lt;/em&gt; test harness.&lt;/p&gt;

&lt;h2 id=&quot;whats-special-about-the-marionette-test-harness&quot;&gt;What’s special about the Marionette test harness?&lt;/h2&gt;

&lt;p&gt;Um, like, duh, it’s made for tests using Marionette!&lt;/p&gt;

&lt;p&gt;What I mean is that unlike an all-purpose test harness, the Marionette harness already knows that you’re a Mozillian specifically interested in is running Gecko-based browser tests using Marionette. So instead of making you write code in for setup/teardown/logging/etc. that talks to Marionette and uses other features of the Mozilla ecosystem, it does that legwork for you.&lt;/p&gt;

&lt;p&gt;You still have control, though; it makes it easy for you to make decisions about certain Mozilla-/Gecko-specific properties that could affect your tests, like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Need to use a specific Firefox binary? Or a particular Firefox instance running on a device somewhere?&lt;/li&gt;
  &lt;li&gt;Got a special profile or set of preferences you want the browser to run with?&lt;/li&gt;
  &lt;li&gt;Want &lt;a href=&quot;https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox&quot;&gt;Electrolysis&lt;/a&gt; enabled, or not?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As well as some more general decisions, like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Need to run an individual test module? A directory full of tests? Tests listed in a manifest file?&lt;/li&gt;
  &lt;li&gt;Want the tests run multiple times? Or in chunks?&lt;/li&gt;
  &lt;li&gt;How and where should the results be logged?&lt;/li&gt;
  &lt;li&gt;Care to drop into a debugger if something goes wrong?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But how does it do all this? What does it look like on the inside? Let’s dive into the code to find out.&lt;/p&gt;

&lt;h2 id=&quot;how-does-the-marionette-harness-work&quot;&gt;How does the Marionette harness work?&lt;/h2&gt;

&lt;p&gt;Inside Marionette, in the file &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runtests.py#30&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;harness/marionette/runtests.py&lt;/code&gt;&lt;/a&gt;, we find the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteHarness&lt;/code&gt; class. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteHarness&lt;/code&gt; itself is quite simple: it takes in a set of &lt;em&gt;arguments&lt;/em&gt; that specify the desired preferences with respect to the type of decisions we just mentioned, uses an &lt;em&gt;argument parser&lt;/em&gt; to parse and process those arguments, and then passes them along to a &lt;em&gt;test runner&lt;/em&gt;, which runs the tests accordingly.&lt;/p&gt;

&lt;p&gt;So actually, it’s the “test runner” that does the brunt of the work of a test harness here. Perhaps for that reason, the names “Marionette Test Harness” and “Marionette Test Runner” sometimes seem to be used interchangeably, which I for one found quite confusing at first.&lt;/p&gt;

&lt;p&gt;Anyway, the test runner that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteHarness&lt;/code&gt; makes use of is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteTestRunner&lt;/code&gt; class defined in &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runtests.py#18&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtests.py&lt;/code&gt;&lt;/a&gt;, but that’s really just a little wrapper around &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteTestRunner&lt;/code&gt; from &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#491&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;harness/marionette/runner/base.py&lt;/code&gt;&lt;/a&gt;, which is where the magic happens – and also where I’ve spent most of my time for my &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;Outreachy&lt;/a&gt; &lt;a href=&quot;/blog/outreachy-halftime-ish-update/&quot;&gt;internship&lt;/a&gt;, but more on that later. For now let’s check out the runner!&lt;/p&gt;

&lt;h3 id=&quot;how-does-marionettes-test-runner-work&quot;&gt;How does Marionette’s test runner work?&lt;/h3&gt;

&lt;p&gt;The beating heart of the Marionette test runner is the method &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#860-931&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt;&lt;/a&gt;. By combining some methods that take care of general test-harness functionality and some methods that let us set up and keep tabs on a Marionette client-server session, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt; gives us the Marionette-centric test harness we never knew we always wanted. Thanks, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;To get an idea of how the test runner works, let’s take a walk through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt; method and see what it does.&lt;sup id=&quot;a2&quot;&gt;&lt;a href=&quot;#f2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;First of all, it simply &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#861-862&quot;&gt;initializes&lt;/a&gt; some things, e.g. timers and counters for passed/failed tests. So far, so boring.&lt;/p&gt;

&lt;p&gt;Next, we get to the part that puts the “Marionette” in “Marionette test runner”. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt; method &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#864-865&quot;&gt;starts up Marionette&lt;/a&gt;, by &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#815&quot;&gt;creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Marionette&lt;/code&gt; object&lt;/a&gt; – passing in the appropriate &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#688-749&quot;&gt;arguments&lt;/a&gt; based on the runner’s settings – which gives us the client-server session we need to automate the browser in the tests we’re about to run (we know how that all works from &lt;a href=&quot;/blog/marionette-act-i-automation/&quot;&gt;Act I&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#867&quot;&gt;Adding the tests we want&lt;/a&gt; to the runner’s to-run list (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.tests&lt;/code&gt;) is the next step. This means &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#964-1021&quot;&gt;finding&lt;/a&gt; the appropriate tests from test modules, a directory containing test modules, or a manifest file listing tests and the conditions under which they should be run.&lt;/p&gt;

&lt;p&gt;Given those tests, after  &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#869-880&quot;&gt;gathering&lt;/a&gt; and &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#882-888&quot;&gt;logging&lt;/a&gt; some info about the settings we’re using, we’re ready to &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#897&quot;&gt;run&lt;/a&gt;! (&lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#892-898&quot;&gt;Perhaps multiple times&lt;/a&gt;,  if repeated runs were requested.)&lt;/p&gt;

&lt;p&gt;To actually run the tests, the runner calls   &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1082-1099&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test_sets&lt;/code&gt;&lt;/a&gt;, which runs the tests we added earlier, possibly dividing them into several sets (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chunks&lt;/code&gt;) that will be run separately (thus enabling parallelization). This in turn calls &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1072-1080&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test_set&lt;/code&gt;&lt;/a&gt;, which basically just calls &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1023-1070&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test&lt;/code&gt;&lt;/a&gt;, which is the &lt;a href=&quot;https://en.wikipedia.org/wiki/Turtles_all_the_way_down&quot;&gt;final turtle&lt;/a&gt;.&lt;sup id=&quot;a3&quot;&gt;&lt;a href=&quot;#f3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Glancing at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test&lt;/code&gt;, we can see how the Marionette harness is &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1025-1026&quot;&gt;based&lt;/a&gt; on Python’s &lt;a href=&quot;https://docs.python.org/2/library/unittest.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt;&lt;/a&gt;, which is why the tests we run with this harness basically look like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt; tests (we’ll say a bit more about that below). Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt; to &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1041&quot;&gt;discover&lt;/a&gt; our test cases in the modules we provided, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test&lt;/code&gt; &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1050-1051&quot;&gt;runs&lt;/a&gt; each test using a &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#217&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteTextTestRunner&lt;/code&gt;&lt;/a&gt; and gets back a &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#61&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteTestResult&lt;/code&gt;&lt;/a&gt;. These are basically Marionette-specific versions of classes from &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/mozbase/moztest&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;moztest&lt;/code&gt;&lt;/a&gt;, which helps us store the test results in a format that’s compatible with other Mozilla automation tools, like &lt;a href=&quot;https://wiki.mozilla.org/Auto-tools/Projects/Treeherder&quot;&gt;Treeherder&lt;/a&gt;. Once we’ve got the test result, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test&lt;/code&gt; simply &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1053-1066&quot;&gt;adds it to the runner’s tally&lt;/a&gt; of test successes/failures.&lt;/p&gt;

&lt;p&gt;So, that’s how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt; (and its helper functions) execute the tests. Once all the tests have been run, our main &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt; method basically just &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#911-913,921&quot;&gt;logs some info&lt;/a&gt; about how things went, and which tests passed. After that, the runner &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#927&quot;&gt;cleans up&lt;/a&gt; by &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#1101-1112&quot;&gt;shutting down Marionette and the browser&lt;/a&gt;, even if something &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#904-908,922-925&quot;&gt;went wrong&lt;/a&gt; during the running or logging, or if the user &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/runner/base.py#899-903,929-931&quot;&gt;interrupted&lt;/a&gt; the tests.&lt;/p&gt;

&lt;p&gt;So there we have it: our very own Marionette-centric test-runner! It runs our tests with Marionette and Firefox set up however we want, and also gives us control over more general things like logging and test chunking. In the next section, we’ll take a look at how we can interact with and customize the runner, and tell it how we want our tests run.&lt;/p&gt;

&lt;h3 id=&quot;what-do-the-tests-look-like&quot;&gt;What do the tests look like?&lt;/h3&gt;

&lt;p&gt;As for the tests themselves, since the Marionette harness is an extension of Python’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt;, tests are mostly written as a custom flavor of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt; test cases. Tests extend &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/3ba5426a03b495b6417fffb872d42874edb80855/testing/marionette/harness/marionette/marionette_test.py#617&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteTestCase&lt;/code&gt;&lt;/a&gt;, which is an extension of &lt;a href=&quot;https://docs.python.org/2/library/unittest.html#unittest.TestCase&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest.TestCase&lt;/code&gt;&lt;/a&gt;. So if you need to write a new test using Marionette, it’s as simple as writing a new test module named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_super_awesome_things.py&lt;/code&gt; which extends that class with whatever &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_*&lt;/code&gt; methods you want – just like with vanilla &lt;a href=&quot;https://docs.python.org/2/library/unittest.html#basic-example&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s take a look at a simple example, &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/harness/marionette/tests/unit/test_checkbox.py&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_checkbox.py&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;marionette&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MarionetteTestCase&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;marionette_driver.by&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestCheckbox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MarionetteTestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;test_html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;marionette&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;absolute_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;test.html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;marionette&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;marionette&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;myCheckBox&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This and the other Marionette unit tests can be found in the directory  &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/harness/marionette/tests/unit/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;testing/marionette/harness/marionette/tests/unit/&lt;/code&gt;&lt;/a&gt;, so have a peek there for some more examples.&lt;/p&gt;

&lt;p&gt;Once we’ve got our super awesome new test, we can run it (with whatever super awesome settings we want) using the harness’s command-line interface. Let’s take a look at how that interface works.&lt;/p&gt;

&lt;h3 id=&quot;what-is-the-interface-to-the-harness-like&quot;&gt;What is the interface to the harness like?&lt;/h3&gt;

&lt;p&gt;Let’s peek at the &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runner/base.py#496-582&quot;&gt;constructor method&lt;/a&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteTestRunner&lt;/code&gt; class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BaseMarionetteTestRunner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app_args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;profile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;testvars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;symbols_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shuffle_seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this_chunk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_chunks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;server_root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gecko_log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result_callbacks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;prefs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_tags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;socket_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BaseMarionetteArguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket_timeout_default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;startup_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addons&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workspace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e10s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;emulator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;!--** --&gt;

&lt;p&gt;Our first thought might be, “Wow, that’s a lot of arguments”. Indeed! This is how the runner knows how you want the tests to be run. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;binary&lt;/code&gt; is the path to the specific Firefox application binary you want to use, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e10s&lt;/code&gt; conveys whether or not you want to run Firefox with multiple processes.&lt;/p&gt;

&lt;p&gt;Where do all these arguments come from? They’re &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runtests.py#67&quot;&gt;passed&lt;/a&gt; to the runner by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteHarness&lt;/code&gt;, which &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runtests.py#51-52&quot;&gt;gets them&lt;/a&gt; from the &lt;em&gt;argument parser&lt;/em&gt; we mentioned earlier, &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runtests.py#24-27&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteArguments&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Analogous to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteTestRunner&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteTestRunner&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteArgument&lt;/code&gt; is just a small wrapper around &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteArguments&lt;/code&gt; from &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runner/base.py#241&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runner/base.py&lt;/code&gt;&lt;/a&gt;, which in turn is just an extension of Python’s &lt;a href=&quot;https://docs.python.org/2/library/argparse.html#argparse.ArgumentParser&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;argparse.ArgumentParser&lt;/code&gt;&lt;/a&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteArguments&lt;/code&gt; defines which &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runner/base.py#254-373&quot;&gt;arguments&lt;/a&gt; can be passed in to the harness’s &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runtests.py#72-92&quot;&gt;command-line interface&lt;/a&gt; to configure its settings. It also &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runner/base.py#419&quot;&gt;verifies&lt;/a&gt; that whatever arguments the user passed in make sense and don’t contract each other.&lt;/p&gt;

&lt;p&gt;To actually &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Marionette_Test_Runner&quot;&gt;use the harness&lt;/a&gt;, we can simply call the &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/harness/marionette/runtests.py&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtests.py&lt;/code&gt;&lt;/a&gt; script with: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python runtests.py [whole bunch of awesome arguments]&lt;/code&gt;. Alternatively, we can use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/mach&quot;&gt;Mach command&lt;/a&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;marionette-test&lt;/code&gt; (which just calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runtests.py&lt;/code&gt;), as described &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Running_Tests&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To see all of the available command-line options (there are a lot!), you can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python runtests.py --help&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./mach marionette-test --help&lt;/code&gt;, which just spits out the arguments and their descriptions as defined in &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/testing/marionette/harness/marionette/runner/base.py#254-373&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteArguments&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, with the simple command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mach marionette-test [super fancy arguments] test_super_fancy_things.py&lt;/code&gt;, you can get the harness to run your Marionette tests with whatever fancy options you desire to fit your specific fancy scenario.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.tenor.co/images/532d794fb57c2b1bfbcedef396e93ce1/raw&quot; alt=&quot;&amp;quot;I'm so fancy&amp;quot; (GIF from &amp;quot;Fancy&amp;quot; by Iggy Azalea)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;Iggy Azalea's &quot;Fancy&quot; via &lt;a href=&quot;https://www.tenor.co/view/fancy-iggyazalea-gif-4448714&quot;&gt;tenor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But what if you’re extra fancy, and have testing needs that exceed the limits of what’s possible with the (copious) command-line options you can pass to the Marionette runner? Worry not! You can customize the runner even further by extending the base classes and making your own super-fancy harness. In the next section, we’ll see how and why you might do that.&lt;/p&gt;

&lt;h2 id=&quot;how-is-the-marionette-test-harness-used-at-mozilla&quot;&gt;How is the Marionette test harness used at Mozilla?&lt;/h2&gt;

&lt;p&gt;Other than enabling people to write and run their own tests using the Marionette client, what is the Marionette harness for? How does Mozilla use it internally?&lt;/p&gt;

&lt;p&gt;Well, first and foremost, the harness is used to run the Marionette Python unit tests we described earlier, which check that Marionette is functioning as expected (e.g. if Marionette tells the browser to check that box, then by golly that box better get checked!). Those are the tests that will get run if you just run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mach marionette-test&lt;/code&gt; without specifying any test(s) in particular.&lt;/p&gt;

&lt;p&gt;But that’s not all! I mentioned above that there might be special cases where the runner’s functionality needs to be extended, and indeed Mozilla has already encountered this scenario a couple of times.&lt;/p&gt;

&lt;p&gt;One example is the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Firefox_UI_tests&quot;&gt;Firefox UI tests&lt;/a&gt;, and in particular the UI update tests. These test the functionality of e.g. clicking the “Update Firefox” button in the UI, which means they need to do things like compare the old version of the application to the updated one to make sure that the update worked. Since this involves binary-managing superpowers that the base Marionette harness doesn’t have, the UI tests have their own runner, &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/firefox-ui/harness/firefox_ui_harness/runners/base.py&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FirefoxUITestRunner&lt;/code&gt;&lt;/a&gt;, which extends &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteTestRunner&lt;/code&gt; with those superpowers.&lt;/p&gt;

&lt;p&gt;Another test suite that makes use of a superpowered harness is the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/external-media-tests&quot;&gt;External Media Tests&lt;/a&gt;, which tests video playback in Firefox and need some extra resources – namely a list of video URLs to make available to the tests. Since there’s no easy way to make such resources available to tests using the base Marionette harness, the external media tests have &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/dom/media/test/external/external_media_harness/runtests.py&quot;&gt;their own test harness&lt;/a&gt; which uses the custom &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/external-media-tests&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MediaTestRunner&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/rev/d5f20820c80514476f596090292a5d77c4b41e3b/dom/media/test/external/external_media_harness/runtests.py#49&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MediaTestArguments&lt;/code&gt;&lt;/a&gt; (extensions of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteTestRunner&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteArguments&lt;/code&gt;, respectively), to allow the user to e.g. specify the video resources to use via the command line.&lt;/p&gt;

&lt;p&gt;So the Marionette harness is used in at least three test suites at Mozilla, and more surely can and will be added as the need arises! Since the harness is designed with automation in mind, suites like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;marionette-test&lt;/code&gt; and the Firefox UI tests can be (and are!) run automatically to make sure that developers aren’t breaking Firefox or Marionette as they make changes to the Mozilla codebase. This all makes the Marionette harness a rather indispensable development tool.&lt;/p&gt;

&lt;p&gt;Which brings us to a final thought…&lt;/p&gt;

&lt;h2 id=&quot;how-do-we-know-that-the-harness-itself-is-running-tests-properly&quot;&gt;How do we know that the harness itself is running tests properly?&lt;/h2&gt;

&lt;p&gt;The Marionette harness, like any test harness, is just another piece of software. It was written by humans, which means that bugs and breakage are always a possibility. Since breakage or bugs in the test harness could prevent us from running tests properly, and we need those tests to work on Firefox and other Mozilla tools, we need to make sure that they get caught!&lt;/p&gt;

&lt;p&gt;Do you see where I’m going with this? We need to… wait for it…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Test the thing that runs the tests&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yup, that’s right: Meta-testing. Test-ception. Tests all the way down.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://media1.popsugar-assets.com/files/thumbor/mQHBZmHnmyaKD5KDQ3Pczk6iM4E/fit-in/1024x1024/filters:format_auto-!!-:strip_icc-!!-/2015/07/21/936/n/1922283/2213f04074cccfc3_raw/i/When-You-Realize-Youre-Getting-Security-Deposit-Back-From-Your-Lease.gif&quot; alt=&quot;&amp;quot;Oh my god&amp;quot; (GIF from the film &amp;quot;Clueless&amp;quot;)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;&lt;em&gt;Clueless&lt;/em&gt; via &lt;a href=&quot;http://www.popsugar.com/entertainment/Clueless-Movie-GIFs-37943154&quot;&gt;POPSUGAR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s what I’ve been doing this summer for my &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner&quot;&gt;Outreachy project&lt;/a&gt;: working on the tests for the Marionette test harness, otherwise known as the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Developer_setup#Marionette_Harness_Unit_Tests&quot;&gt;Marionette harness (unit) tests&lt;/a&gt;. I wrote a bit about what I’ve been up to in my &lt;a href=&quot;/blog/outreachy-halftime-ish-update/&quot;&gt;previous post&lt;/a&gt;, but in my next and final Outreachy post, I’ll explain in more detail what the harness tests do, how we run them in automation, and what improvements I’ve made to them during my time as a Mozilla contributor.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://media2.popsugar-assets.com/files/thumbor/fvDfv9zE69Mw1HJJtn4veTLo6BQ/fit-in/1024x1024/filters:format_auto-!!-:strip_icc-!!-/2015/07/21/935/n/1922283/3c71c918ce03dcce_tumblr_lv6o35jlkv1qb9pa3o1_500/i/When-Youre-Dinner-Weeknight-You-Realize-8-pm.gif&quot; alt=&quot;&amp;quot;I'm outty&amp;quot; (GIF from the film &amp;quot;Clueless&amp;quot;)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;&lt;em&gt;Clueless&lt;/em&gt; via &lt;a href=&quot;http://www.popsugar.com/entertainment/Clueless-Movie-GIFs-37943154&quot;&gt;POPSUGAR&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;notes&quot;&gt;Notes&lt;/h4&gt;

&lt;p&gt;&lt;b id=&quot;f1&quot;&gt;1&lt;/b&gt; Or &lt;a href=&quot;https://www.mozilla.org/en-US/firefox/android/&quot;&gt;Fennec&lt;/a&gt;, or &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS&quot;&gt;B2G&lt;/a&gt;, or [insert &lt;a href=&quot;https://en.wikipedia.org/wiki/Gecko_(software)#Usage&quot;&gt;Gecko-based project&lt;/a&gt; here]… &lt;a href=&quot;#a1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f2&quot;&gt;2&lt;/b&gt; If you scroll through it and think, “Wow, that’s long and ugly”, well, you should’ve seen it before I &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1275269&quot;&gt;refactored&lt;/a&gt; it!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://media3.popsugar-assets.com/files/thumbor/fc9xotgGrHFZI0W6fUakt4MC2Ug/fit-in/1024x1024/filters:format_auto-!!-:strip_icc-!!-/2015/07/21/935/n/1922283/0151951e7852f4d2_hagsville/i/When-You-Look-Your-High-School-Enemies-Facebook-Pages.gif&quot; alt=&quot;&amp;quot;Hagsville&amp;quot; (GIF from the film &amp;quot;Clueless&amp;quot;)&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;credit&quot;&gt;&lt;em&gt;Clueless&lt;/em&gt; via &lt;a href=&quot;http://www.popsugar.com/entertainment/Clueless-Movie-GIFs-37943154&quot;&gt;POPSUGAR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;#a2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f3&quot;&gt;3&lt;/b&gt; If you think distinguishing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_tests&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test_sets&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test_set&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run_test&lt;/code&gt; is confusing, I wholeheartedly agree with you! But best get used to it; working on the Marionette test harness involves developing an eagle-eye for plurals in method names (we’ve also got &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_add_tests&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_test&lt;/code&gt;). &lt;a href=&quot;#a3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">Welcome back to my post series on the Marionette project! In Act I, we looked into Marionette’s automation framework for Gecko, the engine behind the Firefox browser. Here in Act II, we’ll take a look at a complementary side of the Marionette project: the testing framework that helps us run tests using our Marionette-animated browser, aka the Marionette test harness. If – like me at the start of my Outreachy internship – you’re clueless about test harnesses, or the Marionette harness in particular, and want to fix that, you’re in the right place!</summary></entry><entry><title type="html">Outreachy halftime(ish) update</title><link href="http://anjana.dev/blog/outreachy-halftime-ish-update/" rel="alternate" type="text/html" title="Outreachy halftime(ish) update" /><published>2016-08-02T00:00:00+00:00</published><updated>2016-08-02T00:00:00+00:00</updated><id>http://anjana.dev/blog/outreachy-halftime-ish-update</id><content type="html" xml:base="http://anjana.dev/blog/outreachy-halftime-ish-update/">&lt;p&gt;It feels like yesterday that I &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;started my Outreachy internship&lt;/a&gt;, but it was actually over 2 months ago! For the last couple of weeks I’ve been on Outreachy hiatus because of &lt;a href=&quot;https://ep2016.europython.eu/en/&quot;&gt;EuroPython&lt;/a&gt;, moving from &lt;a href=&quot;https://goo.gl/maps/Rp7qp5Dvg5C2&quot;&gt;Saarbrücken to Berlin&lt;/a&gt;, and my mentor being on vacation. Now I’m back, with 6 weeks left in my internship! So it seems like a good moment to check in and reflect on how things have been going so far, and what’s in store for the rest of my time as an Outreachyee.&lt;/p&gt;

&lt;h2 id=&quot;what-have-i-been-up-to&quot;&gt;What have I been up to?&lt;/h2&gt;

&lt;h3 id=&quot;learning-how-to-do-the-work&quot;&gt;Learning how to do the work&lt;/h3&gt;

&lt;p&gt;In the rather involved application process for Outreachy, I already had to spend quite a bit of time figuring out the process for making even the tiniest contribution to the Mozilla codebase. But obviously one can’t learn everything there is to know about a project within a couple of weeks, so a good chunk of my Outreachy time so far was spent on getting better acquainted with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;The tools&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;I’ve already written about my learning experiences with &lt;a href=&quot;/blog/warming-up-to-mercurial/&quot;&gt;Mercurial&lt;/a&gt;, but there were a lot of other components of the Mozilla development process that I had to learn about (and am still learning about), such as &lt;a href=&quot;https://bugzilla.mozilla.org/&quot;&gt;Bugzilla&lt;/a&gt;, &lt;a href=&quot;http://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview.html&quot;&gt;MozReview&lt;/a&gt;, &lt;a href=&quot;https://wiki.mozilla.org/EngineeringProductivity/Projects/Treeherder&quot;&gt;Treeherder&lt;/a&gt;, &lt;a href=&quot;https://wiki.mozilla.org/ReleaseEngineering/TryServer&quot;&gt;Try&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/mach&quot;&gt;Mach&lt;/a&gt;…
Then, since the project I’m working focuses on testing, I had to grok things like &lt;a href=&quot;http://docs.pytest.org/en/latest/&quot;&gt;Pytest&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html&quot;&gt;Mock&lt;/a&gt;. Since most everything I’m doing is in Python, I’ve also been picking up useful Python tidbits here and there.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;The project&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;My internship project, &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner&quot;&gt;“Test-driven refactoring of Marionette’s Python test runner”&lt;/a&gt;, relates to a component of the Marionette project, which encompasses a lot of moving parts. Even figuring out what Marionette is, what components it comprises, how these interrelate, and which of them I need to know about, was a non-trivial task. That’s why I’m writing a couple of posts about the project itself - &lt;a href=&quot;/blog/marionette-act-i-automation/&quot;&gt;one down&lt;/a&gt;, one to go - to crystallize what I’ve learned and hopefully make it a little easier for other people to get through the what-even-is-it steps that I’ve been going through. This post is a sort of “intermission”, so stay tuned for my upcoming post on the Marionette test runner and harness!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;doing-the-work&quot;&gt;Doing the work&lt;/h3&gt;

&lt;p&gt;Of course, there’s a reason I’ve been trying to wrap my head around all the stuff I just mentioned: so that I can actually do this project! So what is the actual work I’ve been doing, i.e. my overall contribution to Mozilla as an Outreachy intern?&lt;/p&gt;

&lt;p&gt;Well, to quote the &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner&quot;&gt;project description&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;we’re testing the thing that runs Firefox tests&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The “thing” is the Marionette test runner, a tool written in Python that allows us to run tests that make use of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt; to automate the browser. It’s responsible for things like discovering which tests we need to run, setting up all the necessary prerequisites, running the tests one by one, and logging all of the results.&lt;/p&gt;

&lt;p&gt;Since the test runner is essentially a program like any other, it can be broken just like any other! And since it’s used in automation to run the tests that let Firefox developers know if some new change they’ve introduced breaks something, if the test runner itself breaks, that could cause a lot of problems. So what do we do? We test it!&lt;/p&gt;

&lt;p&gt;That’s where I come in. My mentor, Maja, had started writing some unit tests for the test runner before the internship began. My job is basically to add more tests. This involves:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Reading &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/harness/marionette/runner/base.py&quot;&gt;the code&lt;/a&gt; to identify things that could break and cause problems, and thus should be tested&lt;/li&gt;
  &lt;li&gt;Writing &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1275288&quot;&gt;new&lt;/a&gt; &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1276974&quot;&gt;unit&lt;/a&gt; &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1287591#c4&quot;&gt;tests&lt;/a&gt; using Pytest&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1275269&quot;&gt;Refactoring&lt;/a&gt; the code to make it easier to test, more readable, easier to extend/change, or otherwise better&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aside from the testing side of things, another aspect of the project (which I particularly enjoy) involves improving how the runner relates to the rest of the world. For example, improving the &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1237958&quot;&gt;command line interface&lt;/a&gt; to the runner, or making sure the unit tests for the runner are producing &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1285299&quot;&gt;logs&lt;/a&gt; that play nicely with the rest of the Mozilla ecosystem.&lt;/p&gt;

&lt;h3 id=&quot;writing-stuff-down&quot;&gt;Writing stuff down&lt;/h3&gt;

&lt;p&gt;As you can see, I’ve also been spending a fair bit of time writing blog &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;p&lt;/a&gt;&lt;a href=&quot;/blog/warming-up-to-mercurial/&quot;&gt;o&lt;/a&gt;&lt;a href=&quot;/blog/i-want-to-mock-with-you/&quot;&gt;s&lt;/a&gt;&lt;a href=&quot;/blog/mozilla-london-all-hands-2016/&quot;&gt;t&lt;/a&gt;&lt;a href=&quot;/blog/marionette-act-i-automation/&quot;&gt;s&lt;/a&gt; about what I’ve been learning and encountering over the course of my internship. Hopefully these have been or will be useful to others who might also be wrapping their heads around these things for the first time. But regardless, writing them has certainly been useful for me!&lt;/p&gt;

&lt;h2 id=&quot;whats-been-fun&quot;&gt;What’s been fun?&lt;/h2&gt;

&lt;h3 id=&quot;learning-all-the-things&quot;&gt;Learning all the things&lt;/h3&gt;

&lt;p&gt;While working with a new system or technology can often be frustrating, especially when you’re used to something similar-but-not-quite-the-same (ahem, &lt;a href=&quot;/blog/warming-up-to-mercurial/&quot;&gt;git and hg&lt;/a&gt;), I’ve found that the frustration does subside (or at least lessen) eventually, and in its place you find not only the newfound ease of working with the new thing, but also the gratification that comes with the realization: “Hey! I learned the thing!” This makes the overall experience of grappling with the learning curve fun, in my experience.&lt;/p&gt;

&lt;h3 id=&quot;working-remotely&quot;&gt;Working remotely&lt;/h3&gt;

&lt;p&gt;This internship has been my first experience with a lifestyle that always attracted me: working remotely. I love the freedom of being able to work from home if I have things to take care of around the house, or at a cafe if I just really need to sip on a Chocolate Chai Soy Latte right now, or from the public library if I want some peace &amp;amp; quiet. I also loved being able to escape Germany for 2 weeks to visit my boyfriend’s family in Italy, or to work a day out of the Berlin office if I’m there for a long weekend looking at apartments. Now that I’ve moved to Berlin, I love the option of working out of the office here if I want to, or working from home or a cafe if I have things I need to take care of on the other side of the city. And because the team I’m working on is also completely distributed, there’s a great infrastructure already in place (IRC, video conferences, collaborative documents) to enable us to work in completely different countries/time zones and still feel connected.&lt;/p&gt;

&lt;h3 id=&quot;helping-others-get-started-contributing&quot;&gt;Helping others get started contributing!&lt;/h3&gt;

&lt;p&gt;A couple of weeks ago I got to mentor my first bug on Bugzilla, and help someone else get started contributing to the thing that I had gotten started contributing to a few months ago for my Outreachy internship. Although it was a pretty simple &amp;amp; trivial thing, it felt great to help someone else get involved, and to realize I knew the answers to a couple of their questions, meaning that I’m actually already involved! That’s the kind of thing that really makes me want to continue working with FOSS projects after my internship ends, and makes me so appreciative of initiatives like Outreachy that help bring newcomers like me into this community.&lt;/p&gt;

&lt;h2 id=&quot;whats-been-hard&quot;&gt;What’s been hard?&lt;/h2&gt;

&lt;h3 id=&quot;impostor-syndrome&quot;&gt;Impostor Syndrome&lt;/h3&gt;

&lt;p&gt;The flip side of the learning-stuff fun is that, especially at the beginning, ye olde Impostor Syndrome gets to run amok. When I started my internship, I had the feeling that I had Absolutely No Idea what I was doing – over the past couple of months it has gotten gradually better, but I still have the feeling that I have a Shaky and Vague Idea of what I’m doing. From my communications with other current/former Outreachy interns, this seems to be par for the course, and I suppose it’s par for the course for anyone joining a new project or team for the first time. But even if it’s normal, it’s still there, and it’s still hard.&lt;/p&gt;

&lt;h3 id=&quot;working-remotely-1&quot;&gt;Working remotely&lt;/h3&gt;

&lt;p&gt;As I mentioned, overall I’ve been really enjoying the remote-work lifestyle, but it does have its drawbacks. When working from home, I find it incredibly difficult to separate my working time from my not-working time, which is most often manifested in my complete inability to stop working at the end of the day. Because I don’t have to physically walk away from my computer, at the end of the day I think “Oh, I’ll just do that one last thing,” and the next thing I know the Last Thing has led to 10 other Last Things and now it’s 11:00pm and I’ve been working for 13 hours straight. Not healthy, not fun. Also, while the flexibility and freedom of not having a fixed place of work is great, moving around (e.g. from Germany to Italy to other side of Germany) can also be chaotic and stressful, and can make working (productively) more difficult – especially if you’re not sure where your next internet is going to come from. So the remote work thing is really a double-edged sword, and doing in a way that preserves both flexibility and stability is clearly a balancing act that takes some practice. I’m working on it.&lt;/p&gt;

&lt;h3 id=&quot;measuring-productivity&quot;&gt;Measuring productivity&lt;/h3&gt;

&lt;p&gt;Speaking of working productively, how do you know when you’re doing it? Is spending a whole day reading about mock objects, or writing a blog post, or banging your head against a build failure, or [insert activity that is not writing 1000 lines of code] productive? The nature of the Outreachy system is that every project is different, and the target outcomes (or lack thereof) are determined by the project mentor, and whether or not your work is satisfactory is entirely a matter of their judgment. Luckily, my mentor is extremely fair, open, clear, and realistic about her goals for the project. She’s also been very reassuring when I’ve expressed uncertainty about productivity, and forthcoming about her satisfaction with my progress. But I feel like this is just my good luck having a mentor who a) is awesome and b) was an Outreachy intern herself once, and can thus empathize. I do wonder how my experience would be different, especially from the standpoint of knowing whether I’m measuring up to expectations, if I were on a different project with a different mentor. Which brings me to…&lt;/p&gt;

&lt;h2 id=&quot;whats-been-helpful&quot;&gt;What’s been helpful?&lt;/h2&gt;

&lt;h3 id=&quot;having-a-fantastic-mentor&quot;&gt;Having a fantastic mentor&lt;/h3&gt;

&lt;p&gt;As I’ve just said, I feel really lucky to be working with my mentor, Maja. She’s been an incredible support throughout the internship, and has just made it a great experience. I’m really thankful for her for being so detailed &amp;amp; thorough in her initial conception of the project and instructions to me, and for being so consistently responsive and helpful with any of my questions or concerns. I can’t imagine a better mentor.&lt;/p&gt;

&lt;h3 id=&quot;being-part-of-a-team&quot;&gt;Being part of a team&lt;/h3&gt;

&lt;p&gt;“It takes a village,” or whatever they say, and my village is the Automation crew (who hang out in &lt;a href=&quot;irc://irc.mozilla.org/#automation&quot;&gt;#automation&lt;/a&gt; on IRC) within the slightly-larger village of the Engineering Productivity team (A-Team) (&lt;a href=&quot;irc://irc.mozilla.org/#ateam&quot;&gt;#ateam&lt;/a&gt;). Just like my mentor, the rest of the crew and the team have also been really friendly and helpful to me so far. If Maja’s not there, if I’m working on some adjacent component, or if I have some general question, they’ve been there for me. And while having a fantastic mentor is fantastic, having a fantastic mentor within a fantastic team is double-fantastic, because it helps with the hard things like learning new tools or working remotely (especially when your mentor is in a different time zone, but other team members are in yours). So I’m also really grateful to the whole team for taking me in and treating me as one of their own.&lt;/p&gt;

&lt;h3 id=&quot;attending-the-all-hands&quot;&gt;Attending the All Hands&lt;/h3&gt;

&lt;p&gt;Apparently, at some point in the last couple of years, someone at Mozilla decided to start including Outreachy interns in the semi-annual All Hands meetings. Whoever made that decision: please accept my heartfelt thanks. Being included in the &lt;a href=&quot;/blog/mozilla-london-all-hands-2016/&quot;&gt;London All Hands&lt;/a&gt; made a real difference - not only because I understood a lot about various components of the Mozilla infrastructure that had previously been confusing or unclear to me, but also because the chance to meet and socialize with team members and other Outreachy interns face-to-face was a huge help in dealing with e.g. Impostor Syndrome and the challenges of working on a distributed team. I’m so glad I was able to join that meeting, because it really helped me feel more bonded to both Mozilla as a whole and to my specific team/project, and I hope for the sake of both Mozilla and Outreachy that Outreachyees continue to be invited to such gatherings.&lt;/p&gt;

&lt;h3 id=&quot;intern-solidarity&quot;&gt;Intern solidarity&lt;/h3&gt;

&lt;p&gt;Early on in the internship, one of the other Mozilla Outreachy interns started a channel just for us on Mozilla’s IRC. Having a “safe space” to check in with the other interns, ask “dumb” questions, express insecurities/frustrations, and just generally support each other is immensely helpful. On top of that, several of us got to hang out in person at the London All Hands meeting, which was fantastic. Having contact with a group of other people going through more or less the same exciting/bewildering/overwelming/interesting experience you are is invaluable, especially if you suffer from Impostor Syndrome as so many of us do. So I’m so grateful to the other interns for their support and solidarity.&lt;/p&gt;

&lt;h2 id=&quot;whats-up-next&quot;&gt;What’s up next?&lt;/h2&gt;

&lt;p&gt;In the remaining weeks of my internship, I’m going to be continuing the work I mentioned, but instead of from a library in a small German town or a random internet connection in a small Italian town, I’ll be working mainly out of the Berlin office, and hopefully getting to know more Mozillians here. I’ll also be participating in the &lt;a href=&quot;https://wiki.mozilla.org/TechSpeakers&quot;&gt;TechSpeakers&lt;/a&gt; program, a training program from the Mozilla Reps to improve your public speaking skills so that you can go forth and spread the word about Mozilla’s awesome technologies. Finally, in the last week or two, I’ll be figuring out how to pass the baton, i.e. tie up loose ends, document what I’ve done and where I’m leaving off, and make it possible for someone else – whether existing team or community members, or perhaps the next intern – to continue making the Marionette test runner and its unit tests Super Awesome. And blogging all the while, of course. :) Looking forward to it!&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">It feels like yesterday that I started my Outreachy internship, but it was actually over 2 months ago! For the last couple of weeks I’ve been on Outreachy hiatus because of EuroPython, moving from Saarbrücken to Berlin, and my mentor being on vacation. Now I’m back, with 6 weeks left in my internship! So it seems like a good moment to check in and reflect on how things have been going so far, and what’s in store for the rest of my time as an Outreachyee.</summary></entry><entry><title type="html">Marionette, Act I: We’ve got Firefox on a string</title><link href="http://anjana.dev/blog/marionette-act-i-automation/" rel="alternate" type="text/html" title="Marionette, Act I: We’ve got Firefox on a string" /><published>2016-07-08T00:00:00+00:00</published><updated>2016-07-08T00:00:00+00:00</updated><id>http://anjana.dev/blog/marionette-act-i-automation</id><content type="html" xml:base="http://anjana.dev/blog/marionette-act-i-automation/">&lt;p&gt;As you &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;may already know&lt;/a&gt;, I’m spending my summer interning with Mozilla’s &lt;a href=&quot;https://wiki.mozilla.org/EngineeringProductivity&quot;&gt;Enginering Productivity&lt;/a&gt; team through the &lt;a href=&quot;https://gnome.org/outreachy&quot;&gt;Outreachy&lt;/a&gt; program. Specifically, the project I’m working on is called &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner_.5Bno_longer_taking_applicants.5D&quot;&gt;Test-driven Refactoring of Marionette’s Python Test Runner&lt;/a&gt;. But what exactly does that mean? What is Marionette, and what does it have to do with testing?&lt;/p&gt;

&lt;p&gt;In this two-part series, I’d like to share a bit of what I’ve learned about the Marionette project, and how its various components help us test Firefox by allowing us to automatically control the browser from within. Today, in Act I, I’ll give an overview of how the Marionette server and client make the browser our puppet. Later on, in Act II, I’ll describe how the Marionette test harness and runner make automated testing a breeze, and let you in on the work I’m doing on the Marionette test runner for my internship.&lt;/p&gt;

&lt;p&gt;And since we’re talking about puppets, you can bet there’s going to be a hell of a lot of &lt;a href=&quot;http://www.imdb.com/title/tt0120601/&quot;&gt;&lt;em&gt;Being John Malkovich&lt;/em&gt;&lt;/a&gt; references. Consider yourself warned!&lt;/p&gt;

&lt;!--/excerpt--&gt;

&lt;h2 id=&quot;how-do-you-test-a-browser&quot;&gt;How do you test a browser?&lt;/h2&gt;

&lt;p&gt;On the one hand, you probably want to make sure that the browser’s interface, or &lt;em&gt;chrome&lt;/em&gt;, is working as expected; that users can, say, open and close tabs and windows, type into the search bar, change preferences and so on. But you probably also want to test how the browser displays the actual web pages, or &lt;em&gt;content&lt;/em&gt;, that you’re trying to, well, browse; that users can do things like click on links, interact with forms, or play video clips from their favorite movies.&lt;/p&gt;

&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/LU19Rqy1s9Y&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p class=&quot;caption&quot;&gt;Because let's be honest, that's like 96% of the point of the internet right there, no?&lt;/p&gt;

&lt;p&gt;These two parts, chrome and content, are the main things the browser has to get right. So how do you test them?&lt;/p&gt;

&lt;p&gt;Well, you could launch the browser application, type “Being John Malkovich” into the search bar and hit enter, check that a page of search results appears, click on a YouTube link and check that it takes you to a new page and starts playing a video, type “I ❤️ Charlie Kaufman and Spike Jonze” into the comment box and press enter, check that it submits the text…&lt;/p&gt;

&lt;p&gt;And when you’re done, you could write up a report about what you tested, what worked and what didn’t, and what philosophical discoveries about the nature of identity and autonomy you made along the way.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://67.media.tumblr.com/tumblr_lzoteetytB1r7xg3oo1_1280.png&quot; alt=&quot;Still from the film &amp;quot;Being John Malkovich&amp;quot; in which a marionette puppet regards itself in a mirror&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Am &lt;em&gt;I&lt;/em&gt; the puppet? AM I?&lt;br /&gt;
&lt;span class=&quot;credit&quot;&gt;&lt;em&gt;Being John Malkovich&lt;/em&gt; via &lt;a href=&quot;http://lecoada.tumblr.com/post/17940837987/hysterically-dramatic-puppetry-in-being-john&quot;&gt;COADA on Tumblr&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;Now, while this would be fun, if you have to do it a million times it would be less fun, and your boss might think that it is not fun at all that it takes you an entire developer-hour to test one simple interaction and report back.&lt;/p&gt;

&lt;p&gt;Wouldn’t it be better if we could magically automate the whole thing? Maybe something like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;magical_automated_browser&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://www.youtube.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;search-bar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Being John Malkovich&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;search-button&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# etc., etc.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;SPOILER ALERT: We can, thanks to the Marionette project!&lt;/p&gt;

&lt;h2 id=&quot;what-is-marionette&quot;&gt;What is Marionette?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt; refers to a suite of tools for automated testing of Mozilla browsers. One important part of the project is an automation framework for Gecko, the engine that powers Firefox. The automation side of Marionette consists of the Marionette server and client, which work together to make the browser your puppet: they give you a nice, simple little wooden handle with which you can pull a bunch of strings, which are tied to the browser internals, to make the browser and the content it’s displaying do whatever you want. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client.do_stuff&lt;/code&gt; code above isn’t even an oversimplification; that’s exactly how easy it becomes to control the browser using Marionette’s client and server. Pretty great right?&lt;/p&gt;

&lt;p&gt;But Marionette doesn’t stop there! In addition to the client &amp;amp; server giving you this easy-peasy apparatus for automatic control of the browser, another facet of the Marionette project - the test harness and runner - provides a full-on framework for automatically running and reporting tests that utilize the automation framework. This makes it easy to set up your puppet and the stage you want it to perform on, pull the strings to make the browser dance, check whether the choreography looked right, and log a review of the performance. I can see the headline now:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Screenwriter Charlie Kaufman enthralls again with a brooding script for automated browser testing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/img/bjm_puppethead_loop.gif&quot; alt=&quot;Animated GIF of a puppet from the film &amp;quot;Being John Malkovich&amp;quot; holding its hand to its head in disappointment&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;&lt;em&gt;You:&lt;/em&gt; GROAN. That's a terrible joke.&lt;br /&gt;
&lt;em&gt;Me:&lt;/em&gt; Sorry, it won't be the last. Hang in there, reader.
&lt;br /&gt;
&lt;span class=&quot;credit&quot;&gt;&lt;em&gt;Being John Malkovich&lt;/em&gt; via &lt;a href=&quot;https://thedissectedfrog.wordpress.com/2014/02/06/25-reasons-alfred-jarry-is-the-merdre/&quot;&gt;the dissected frog&lt;/a&gt; (adapted with &lt;a href=&quot;http://gifmaker.me/&quot;&gt;GIFMaker.me&lt;/a&gt;)&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;As I see it, the overall aim of the Marionette project is to make automated browser testing easy. This breaks down into two main tasks:  automation and testing. Here in Act I, we’ll investigate how the Marionette server and client let us automate the browser. In the next post, Act II, we’ll take a closer look at how the Marionette test harness and runner make use of that automation to test the browser.&lt;/p&gt;

&lt;h2 id=&quot;how-do-marionettes-server-and-client-automate-the-browser&quot;&gt;How do Marionette’s server and client automate the browser?&lt;/h2&gt;

&lt;p&gt;A real marionette is composed of three parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a puppet&lt;/li&gt;
  &lt;li&gt;strings&lt;/li&gt;
  &lt;li&gt;a handle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a great analogy for Marionette’s approach to automating the browser (I guess that’s why they named it that).&lt;/p&gt;

&lt;p&gt;The puppet we want to move is the Firefox browser, or to be precise, the &lt;strong&gt;Gecko browser engine&lt;/strong&gt; underlying it. We want to make all of its  parts – windows, tabs, pages, page elements, scripts, and so forth – dance about as we please.&lt;/p&gt;

&lt;p&gt;The handle we use to control it is the &lt;strong&gt;Marionette client&lt;/strong&gt;, a Python library that gives us an API for accessing and manipulating the browser’s components and mimicking user interactions.&lt;/p&gt;

&lt;p&gt;The strings, which connect handle to puppet and thus make the whole contraption work, are the &lt;strong&gt;Marionette server&lt;/strong&gt;. The server comprises a set of components built in to Gecko (the bottom ends of the strings), and listens for commands coming in from the client (the top ends of the strings).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/marionette_labeled_wide.png&quot; alt=&quot;Annotated picture of a marionette puppet with the handle labeled &amp;quot;Marionette client&amp;quot;, the strings labeled &amp;quot;Marionette server&amp;quot;, and the puppet labeled &amp;quot;Gecko engine&amp;quot;&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;credit&quot; style=&quot;text-align: center;&quot;&gt;Photo adapted from &quot;Marionettes from Being John Malkovich&quot; &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-nd/2.0/legalcode&quot;&gt;by&lt;/a&gt; Alex Headrick, via &lt;a href=&quot;https://www.flickr.com/photos/alexheadrick/10637183205&quot;&gt;Flickr&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-puppet-the-gecko-browser-engine&quot;&gt;The puppet: the Gecko browser engine&lt;/h3&gt;

&lt;p&gt;So far, I’ve been talking about “the browser” as the thing we want to automate, and the browser I have in mind is (desktop) Firefox, which Marionette indeed lets us automate. But in fact, Marionette’s even more powerful than that; we can also use it to automate other products, like &lt;a href=&quot;https://www.mozilla.org/en-US/firefox/android/&quot;&gt;Firefox for Android&lt;/a&gt; (codenamed “Fennec”, so cute!) or &lt;a href=&quot;https://www.mozilla.org/en-US/firefox/os/&quot;&gt;FirefoxOS&lt;/a&gt;/&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS&quot;&gt;Boot to Gecko (B2G)&lt;/a&gt;. That’s because the puppet Marionette lets us control is actually not the Firefox desktop browser itself, but rather the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Gecko&quot;&gt;Gecko browser engine&lt;/a&gt; on top of which Firefox (like Fennec, and B2G) is built. All of the above, and any other &lt;a href=&quot;https://en.wikipedia.org/wiki/Gecko_(software)#Usage&quot;&gt;Gecko-based products&lt;/a&gt;, can in principle be automated with Marionette.&lt;sup id=&quot;a1&quot;&gt;&lt;a href=&quot;#f1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup&gt;, &lt;/sup&gt;&lt;sup id=&quot;a2&quot;&gt;&lt;a href=&quot;#f2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/bjm_marionettes_logos.jpg&quot; alt=&quot;Picture of three marionette puppets with Fennec, Firefox, and B2G logos instead of heads&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Just choose your puppet!&lt;br /&gt;
&lt;span class=&quot;credit&quot;&gt;Adapted from &quot;Marionettes from Being John Malkovich&quot; &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-nd/2.0/legalcode&quot;&gt;by&lt;/a&gt; Alex Headrick via &lt;a href=&quot;https://www.flickr.com/photos/alexheadrick/10637183205&quot;&gt;Flickr&lt;/a&gt;, with logos from &lt;a href=&quot;https://twitter.com/FennecNightly&quot;&gt;@FennecNightly&lt;/a&gt;, &lt;a href=&quot;https://www.mozilla.org/en-US/styleguide/identity/firefox/branding/&quot;&gt;Firefox branding&lt;/a&gt;, and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS&quot;&gt;B2G OS&lt;/a&gt;.&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;So what exactly is this Gecko thing we’re playing with? Well, I’ve already revealed that it’s a &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_browser_engine&quot;&gt;browser engine&lt;/a&gt; - but if you’re like me at the beginning of this internship, you’re wondering what a “browser engine” even is/does. &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Gecko&quot;&gt;MDN&lt;/a&gt; explains:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Gecko’s function is to read web content, such as HTML, CSS, XUL, JavaScript, and render it on the user’s screen or print it. In XUL-based applications Gecko is used to render the application’s user interface as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, a browser engine like Gecko takes all that ugly raw HTML/CSS/JS code and turns it into a pretty picture on your screen (or, you know, &lt;a href=&quot;http://www.theworldsworstwebsiteever.com/&quot;&gt;not so pretty&lt;/a&gt; - but a picture, nonetheless), which explains why browser engines are also called “layout engines” or “rendering engines”.&lt;/p&gt;

&lt;p&gt;And see that bit about “XUL”? Well, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL&quot;&gt;XUL&lt;/a&gt; (XML User interface Language) is a markup language Mozilla came up with that lets you write application interfaces almost &lt;a href=&quot;https://en.wikipedia.org/wiki/XUL&quot;&gt;as if they were web pages&lt;/a&gt;. This lets Mozilla use Gecko not only to render the websites that Firefox lets you navigate to, but also to render the interface of Firefox itself: the search bar, tabs, forward and back buttons, etc. So it’s safe to say that Gecko is the heart of Firefox. And other applications, like the aforementioned Fennec and FirefoxOS, as well as the Thunderbird email client.&lt;/p&gt;

&lt;p&gt;But wait a minute; why do we have to go all the way down to Gecko to control the browser? It’s pretty easy to write add-ons to control Firefox’s &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/noverflow/&quot;&gt;chrome&lt;/a&gt; or &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/millennials-to-snake-people/&quot;&gt;content&lt;/a&gt;, so why can’t we just do that? Well, first of all, &lt;a href=&quot;https://en.wikipedia.org/wiki/Add-on_(Mozilla)#Security&quot;&gt;security&lt;/a&gt; issues abound in add-on territory, which is why add-ons typically &lt;a href=&quot;https://support.google.com/chrome_webstore/answer/186213?hl=en&amp;amp;ref_topic=6238977&quot;&gt;run with limited privileges&lt;/a&gt; and/or &lt;a href=&quot;https://blog.mozilla.org/addons/2015/04/15/the-case-for-extension-signing/&quot;&gt;require approval&lt;/a&gt;; so an add-on-based automation system would likely give under- or over-powered control over the browser. But in fact, the real reason Marionette isn’t an add-on is more historical. As browser automation expert and Mozillian David Burns explained at &lt;a href=&quot;https://youtu.be/cU6GML70cR4?t=6m40s&quot;&gt;SeleniumConf 2013&lt;/a&gt;, Marionette was originally developed to test FirefoxOS, which had the goal of using Gecko to run the entire operating system of a smartphone (hence FirefoxOS being codenamed &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/B2G_OS&quot;&gt;Boot to Gecko&lt;/a&gt;). FirefoxOS didn’t allow add-ons, so the Marionette team had to get creative and build an automation solution right into Gecko itself. This gave them the opportunity to make Marionette an implementation of the &lt;a href=&quot;http://w3c.github.io/webdriver/webdriver-spec.html&quot;&gt;WebDriver&lt;/a&gt; specification, a W3C standard for a browser automation interface. The decision to build Marionette as part of Gecko rather than an add-on thus had at least two advantages: Marionette had native access to Gecko and didn’t have to deal with add-on security issues,&lt;sup id=&quot;a3&quot;&gt;&lt;a href=&quot;#f3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; and by making Marionette WebDriver-compliant, Mozilla helped advanced the standardization of browser automation.&lt;/p&gt;

&lt;p&gt;So that’s why it’s Gecko, not Firefox, that Marionette ties strings to. In the next section, we’ll see what those knots look like.&lt;/p&gt;

&lt;h3 id=&quot;the-strings-the-marionette-server&quot;&gt;The strings: the Marionette server&lt;/h3&gt;

&lt;p&gt;As mentioned in the previous section, Marionette is built into Gecko itself. Specifically, the part of Marionette that’s built into Gecko, which gives us native access to the browser’s chrome and content, is called the Marionette server. The server acts as the strings of the contraption: the “top end” listens for commands from the handle (i.e. the Marionette client, which we’ll get to in the next section), and the “bottom end” actually manipulates the Gecko puppet as instructed by our commands.&lt;/p&gt;

&lt;p&gt;The code that makes up these strings is written in JavaScript and lives within the Firefox codebase at &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mozilla-central/testing/marionette&lt;/code&gt;&lt;/a&gt;. Let’s take a little tour, shall we?&lt;/p&gt;

&lt;p&gt;The strings are embedded into Gecko via a component called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteComponent&lt;/code&gt;, which, when enabled,&lt;sup id=&quot;a4&quot;&gt;&lt;a href=&quot;#f4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; starts up a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteServer&lt;/code&gt;, which is the object that most directly represents the strings themselves.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteComponent&lt;/code&gt; is defined in &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/components/marionettecomponent.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;components/marionettecomponent.js&lt;/code&gt;&lt;/a&gt; (which, incidentally, includes &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/components/marionettecomponent.js#209&quot;&gt;the funniest line&lt;/a&gt; in the entire Marionette codebase), while
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteServer&lt;/code&gt; is defined in the file &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/server.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;server.js&lt;/code&gt;&lt;/a&gt;. As you can see in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;server.js&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MarionetteServer&lt;/code&gt; is responsible for tying the whole contraption together: it &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/server.js#85&quot;&gt;sets up a socket&lt;/a&gt; on a given port where it can listen for commands, and &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/server.js#110&quot;&gt;uses the dispatcher&lt;/a&gt; defined in &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/dispatcher.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dispatcher.js&lt;/code&gt;&lt;/a&gt; to receive incoming commands and send data about command outcomes back to the client. Together, the &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/server.js#74&quot;&gt;server&lt;/a&gt; and &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/dispatcher.js#48&quot;&gt;dispatcher&lt;/a&gt; provide a point of connection to the “bottom end” of the strings: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeckoDriver&lt;/code&gt;, or the part of Marionette that actually talks to the browser’s chrome and content.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeckoDriver&lt;/code&gt;, so named because it’s the part of the whole Marionette apparatus that can most accurately be said to be the part &lt;em&gt;automatically driving&lt;/em&gt; Gecko, is defined in a file that is unsurprisingly named &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/driver.js#97&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;driver.js&lt;/code&gt;&lt;/a&gt;. The driver unites a bunch of other specialized modules which control various aspects of the automation, pulling them together and calling on them as needed according to the commands received by the server.
Some examples of the “specialized modules” I’m talking about are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/element.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;element.js&lt;/code&gt;&lt;/a&gt;, which maps out and gives us access to all the elements on the page&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/interaction.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interaction.js&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/action.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;action.js&lt;/code&gt;&lt;/a&gt;, which help us mimic mouse, keyboard, and touchscreen interactions&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/evaluate.js&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;evaluate.js&lt;/code&gt;&lt;/a&gt;, which lets us execute JavaScript code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the help of such modules, the driver allows us to grab on to whatever part of the browser’s chrome or content interests us and interact with it as we see fit.&lt;/p&gt;

&lt;p&gt;The Marionette server thus lets us communicate automatically with the browser, acting as the strings that get tugged on by the handle and in turn pull on the various limbs of our Gecko puppet. The final part of the puzzle, and subject of the next section, is the handle we can use to tell Marionette what it is we want to do.&lt;/p&gt;

&lt;h3 id=&quot;the-handle-the-marionette-client&quot;&gt;The handle: the Marionette client&lt;/h3&gt;

&lt;p&gt;For us puppeteers, the most relevant part of the whole marionette apparatus is the one we actually have contact with: the handle. In Marionette, that handle is called the Marionette client. The client gives us a convenient API for communicating with Gecko via the Marionette server and driver described in the previous section.&lt;/p&gt;

&lt;p&gt;Written in user-friendly Python,&lt;sup id=&quot;a5&quot;&gt;&lt;a href=&quot;#f5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; the client is defined in the confusingly-named &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/client/marionette_driver&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client/marionette_driver&lt;/code&gt;&lt;/a&gt; directory inside of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mozilla-central/testing/marionette&lt;/code&gt;. The client and its API are described quite clearly in the &lt;a href=&quot;http://marionette-client.readthedocs.io/en/latest/&quot;&gt;refreshingly excellent documentation&lt;/a&gt;, which includes a quick &lt;a href=&quot;http://marionette-client.readthedocs.io/en/latest/interactive.html&quot;&gt;tutorial&lt;/a&gt; that walks you through the basic functionality.&lt;/p&gt;

&lt;p&gt;To start pulling Marionette’s strings, all we need to do is instantiate a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Marionette&lt;/code&gt; object (a client), tell it to open up a “session” with the server, i.e. a unique connection that allows messages to be sent back and forth between the two, and give it some &lt;a href=&quot;http://marionette-client.readthedocs.io/en/latest/reference.html&quot;&gt;commands&lt;/a&gt; to send to the server, which (as we saw above) executes them in Gecko. And of course, this assumes that the instance of Firefox (or our Gecko-based product of choice) has Marionette enabled,&lt;sup id=&quot;a4&quot;&gt;&lt;a href=&quot;#f4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; i.e. that there’s a Marionette server ready and waiting for our commands; if the server’s disabled, the strings we’re pulling won’t actually be connected to anything.&lt;/p&gt;

&lt;p&gt;The commands we give can either make changes to the browser’s state (e.g. navigate to a new page, click on an element, resize the window, etc.), or return information about that state (e.g. get the URL of the current page, get the value of a property of a certain element, etc.). When giving commands, we have to be mindful of which &lt;em&gt;context&lt;/em&gt; we’re in, i.e. whether we’re trying to do something with the browser’s &lt;em&gt;chrome&lt;/em&gt; or its &lt;em&gt;content&lt;/em&gt;. Some commands are specific to one context or the other (e.g. navigating to a given URL is a content operation), while others work in both contexts (e.g. clicking on an element can pertain to either of the two). Luckily, the client API gives us an easy one-liner to switch from one context to another.&lt;/p&gt;

&lt;p&gt;Let’s take a look at a little example (see the &lt;a href=&quot;http://marionette-client.readthedocs.io/en/latest/&quot;&gt;docs&lt;/a&gt; for more):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Import browser automation magic
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;marionette&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Marionette&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;marionette_driver.by&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Instantiate the Marionette (client) class
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Marionette&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'localhost'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2828&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Start a session to talk to the server
# (otherwise, nothing will work because the strings aren't connected)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Give a command and check that it worked
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://www.mozilla.org&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;building a better Internet&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Switch to the chrome context for a minute (content is default)
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;using_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CONTEXT_CHROME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;urlbar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;urlbar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;urlbar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;about:robots&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;# try this one out yourself!
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Close the window, which ends the session
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It’s as simple as that! We’ve got an easy-to-use, high-level API that gives us full control over the browser, in terms of both chrome and content. Given this simple handle provided by the client, we don’t really need to worry about the mechanics of the server strings or the Gecko puppet itself; instead, we can concern ourselves with the dance steps we want the browser to perform.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i.imgur.com/pcTBYgJ.jpg&quot; alt=&quot;Still from the film &amp;quot;Being John Malkovich&amp;quot; picturing a life-sized marionette puppet dancing on a stage with ballerinas&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;caption&quot;&gt;Arabesque? Pirouette? Pas de bourrée? You name it!&lt;br /&gt;
&lt;span class=&quot;credit&quot;&gt;&lt;em&gt;Being John Malkovich&lt;/em&gt; via &lt;a href=&quot;http://screenplayhowto.com/beat-sheet/being-john-malkovich/&quot;&gt;ScreenplayHowTo&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-browser-is-our-plaything-now-what&quot;&gt;The browser is our plaything! Now what?&lt;/h2&gt;

&lt;p&gt;So now we’ve seen how the Marionette client and server give us the apparatus to control the browser like a puppet. The client gives us a simple handle we can manipulate, the server ties strings to that handle that transmit our wishes directly to the Gecko browser engine, which dances about as we please.&lt;/p&gt;

&lt;p&gt;But what about checking that it’s got the choreography right? Well, as mentioned above, the client API not only lets us make changes to the browser’s chrome and content, but also gives us information about their current state. And since it’s just regular old Python code, we can use simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assert&lt;/code&gt; statements to perform quick checks, as in the example in the last section. But if we want to test the browser and user interactions with it more thoroughly, we could probably use a more developed and full-featured testing framework.&lt;/p&gt;

&lt;p&gt;ANOTHER SPOILER ALERT (well OK I actually already spoiled this one): the Marionette project gives us a tool for that too!&lt;/p&gt;

&lt;p&gt;In Act II of this article, we’ll explore the Marionette test harness and runner, which wrap the server-client automation apparatus described here in Act I in a testing framework that makes it easy to set the stage, perform a dance, and write a review of the performance. See you back here after the intermission!&lt;/p&gt;

&lt;h4 id=&quot;sources&quot;&gt;Sources&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;The brains of Mozillians David Burns, Maja Frydrychowicz, Henrik Skupin, and Andreas Tolfsen. Many thanks to them for their feedback on this article.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cU6GML70cR4&quot;&gt;From FirefoxDriver to Marionette, Mozilla pulls the strings&lt;/a&gt; - Jonathan Griffin &amp;amp; David Burns, SeleniumConf 2013&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/lfIzRHNXQhM?t=5m7s&quot;&gt;Automating your browser-based testing using WebDriver&lt;/a&gt; - Simon Stewart, Google Tech Talks 2012&lt;/li&gt;
  &lt;li&gt;The Marionette &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette&quot;&gt;codebase&lt;/a&gt; and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;documentation&lt;/a&gt; - Mozilla&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;notes&quot;&gt;Notes&lt;/h4&gt;

&lt;p&gt;&lt;b id=&quot;f1&quot;&gt;1&lt;/b&gt; Emphasis on the “in principle” part, because getting Marionette to play nicely with all of these products may not be trivial. For example, my internship mentor Maja has been hard at work recently on the Marionette runner and client to &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=787203&quot;&gt;make them Fennec-friendly&lt;/a&gt;. &lt;a href=&quot;#a1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f2&quot;&gt;2&lt;/b&gt; If you’re interested in automating a browser that doesn’t run on Gecko, don’t fret! Marionette is Gecko-specific, but it’s an implementation of the engine-agnostic &lt;a href=&quot;http://w3c.github.io/webdriver/webdriver-spec.html&quot;&gt;WebDriver&lt;/a&gt; standard, a W3C specification for a browser automation protocol. Given a WebDriver implementation for the engine in question, any browser can in principle be automated in the same way that Marionette automates Gecko browsers. &lt;a href=&quot;#a2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f3&quot;&gt;3&lt;/b&gt; In fact, Marionette’s built-in design makes it able to circumvent the add-on signing requirement mentioned earlier; this would be dangerous if exposed to end users (see &lt;a href=&quot;#f4&quot;&gt;4&lt;/a&gt;), but comes in handy when Mozilla developers need to inject unsigned add-ons into development versions of Gecko browsers in automation. &lt;a href=&quot;#a3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f4&quot;&gt;4&lt;/b&gt; At this point (or some much-earlier point) you might be wondering:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Wait a minute - if the Marionette server is built into Gecko itself, and gives us full automatic control of the browser, isn’t that a security risk?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Indeed it is. That’s why, although Marionette is indeed built into Gecko and is thus, in a sense, laying dormant in every instance of a Gecko-based application like Firefox, &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/components/marionettecomponent.js#56&quot;&gt;it’s disabled by default &lt;/a&gt; so it can’t be used to control the browser. To run Firefox (or your puppet of choice) with Marionette enabled, you have to be running a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Builds&quot;&gt;Marionette-friendly build&lt;/a&gt; (i.e. a version for developers and not standard users) and &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/components/marionettecomponent.js#109-117&quot;&gt;specifically indicate that you want Marionette turned on when you launch the application&lt;/a&gt;. &lt;a href=&quot;#a4&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f5&quot;&gt;5&lt;/b&gt; Prefer to talk to the Marionette server from another language? No problem! All you need to do is implement a client in your language of choice, which is pretty simple since the &lt;a href=&quot;https://www.w3.org/TR/webdriver/&quot;&gt;WebDriver&lt;/a&gt; specification that Marionette implements uses bog-standard JSON over HTTP for client-server communications. If you want to use JavaScript, your job is even easier: you can take advantage of a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Marionette_JavaScript_Tools&quot;&gt;JS Marionette client&lt;/a&gt; developed for the B2G project. &lt;a href=&quot;#a5&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">As you may already know, I’m spending my summer interning with Mozilla’s Enginering Productivity team through the Outreachy program. Specifically, the project I’m working on is called Test-driven Refactoring of Marionette’s Python Test Runner. But what exactly does that mean? What is Marionette, and what does it have to do with testing? In this two-part series, I’d like to share a bit of what I’ve learned about the Marionette project, and how its various components help us test Firefox by allowing us to automatically control the browser from within. Today, in Act I, I’ll give an overview of how the Marionette server and client make the browser our puppet. Later on, in Act II, I’ll describe how the Marionette test harness and runner make automated testing a breeze, and let you in on the work I’m doing on the Marionette test runner for my internship. And since we’re talking about puppets, you can bet there’s going to be a hell of a lot of Being John Malkovich references. Consider yourself warned!</summary></entry><entry><title type="html">Mozilla London All Hands 2016</title><link href="http://anjana.dev/blog/mozilla-london-all-hands-2016/" rel="alternate" type="text/html" title="Mozilla London All Hands 2016" /><published>2016-06-20T00:00:00+00:00</published><updated>2016-06-20T00:00:00+00:00</updated><id>http://anjana.dev/blog/mozilla-london-all-hands-2016</id><content type="html" xml:base="http://anjana.dev/blog/mozilla-london-all-hands-2016/">&lt;p&gt;Last week, all of Mozilla met in London for a whirlwind tour from TARDIS to TaskCluster, from BBC1 to e10s, from Regent Park to the release train, from Paddington to Positron. As an &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;Outreachy intern&lt;/a&gt;, I felt incredibly lucky to be part of this event, which gave me a chance to get to know Mozilla, my team, and the other interns much better.  It was a jam-packed work week of talks, meetings, team events, pubs, and parties, and it would be impossible to blog about all of the fun, fascinating, and foxy things I learned and did. But I can at least give you some of the highlights! Or, should I say, &lt;em&gt;Who&lt;/em&gt;-lights? (Be warned, that is not the last pun you will encounter here today.)&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Foxy, the TARDIS, and espionage in the park? All in a day&amp;#39;s work at &lt;a href=&quot;https://twitter.com/hashtag/MozLondon?src=hash&quot;&gt;#MozLondon&lt;/a&gt;! &lt;a href=&quot;https://t.co/QPWdPRnJHY&quot;&gt;pic.twitter.com/QPWdPRnJHY&lt;/a&gt;&lt;/p&gt;&amp;mdash; Anjana Vakil (@AnjanaVakil) &lt;a href=&quot;https://twitter.com/AnjanaVakil/status/742853826428997632&quot;&gt;June 14, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!--end-excerpt--&gt;

&lt;h2 id=&quot;role-models&quot;&gt;Role models&lt;/h2&gt;

&lt;p&gt;While watching the plenary session that kicked off the week, it felt great to realize that of the 4 executives emerging from the TARDIS in the corner to take the stage (3 Mozillians and 1 guest star), a full 50% were women. As I had shared with my mentor (also a woman) before arriving in London, one of my goals for the week was to get inspired by finding some new role moz-els (ha!): Mozillians who I could aspire to be like one day, especially those of the female variety.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Why a female role model, specifically? What does gender have to do with it?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, to be a good role model for you, a person needs to not only have a life/career/lego-dragon you aspire to have one day, but also be someone who you can already identify with, and see yourself in, today. A role model serves as a bridge between the two.  As I am a woman, and that is a fundamental part of my experience, a role model who shares that experience is that much easier for me to relate to. I wouldn’t turn down a half-Irish-half-Indian American living in Germany, either.&lt;/p&gt;

&lt;p&gt;At any rate, in London I found no shortage of talented, experienced, and - perhaps most importantly - &lt;em&gt;valued&lt;/em&gt; &lt;a href=&quot;http://www.womoz.org&quot;&gt;women at Mozilla&lt;/a&gt;. I don’t want to single anyone out here, but I can tell you that I met women at all levels of the organization, from intern to executive, who have done and are doing really exciting things to advance both the technology and culture of Mozilla and the web. Knowing that those people exist, and that what they do is possible, might be the most valuable thing I took home with me from London.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Aw, what about the Whomsycorn?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No offense, Whomyscorn, you’re cool too.&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;The Whomsycorn, making its &lt;a href=&quot;https://twitter.com/hashtag/mozlondon?src=hash&quot;&gt;#mozlondon&lt;/a&gt; debut.&lt;br /&gt;&lt;br /&gt;(c/o &lt;a href=&quot;https://twitter.com/shorlander&quot;&gt;@shorlander&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/FirefoxUX&quot;&gt;@FirefoxUX&lt;/a&gt;) &lt;a href=&quot;https://t.co/xEFGcnNZNp&quot;&gt;pic.twitter.com/xEFGcnNZNp&lt;/a&gt;&lt;/p&gt;&amp;mdash; madhava (@madhava) &lt;a href=&quot;https://twitter.com/madhava/status/742702961185423360&quot;&gt;June 14, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;h2 id=&quot;electrolysis-e10s&quot;&gt;Electrolysis (e10s)&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://wiki.mozilla.org/Electrolysis&quot;&gt;Electrolysis&lt;/a&gt;, or “e10s” for those who prefer integers to morphemes, is a massive and long-running initiative to separate the work Firefox does into multiple processes.&lt;/p&gt;

&lt;p&gt;At the moment, the Firefox desktop program that the average user downloads and uses to explore the web runs in a single process. That means that one process has to do all the work of loading &amp;amp; displaying web pages (the browser “content”), as well as the work of displaying the user interface and its various tabs, search bars, sidebars, etc. (the browser “chrome”). So if something goes wrong with, say, the execution of a poorly-written script on a particular page, instead of only that page refusing to load, or its tab perhaps crashing, the entire browser itself may hang or crash.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;That’s not cool. Especially if you often have lots of tabs open. Not that I ever do.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course not. Anyway, even less cool is the possibility that some jerk (not that there are any of those on the internet, though, right?) could make a page with a script that hijacks the entire browser process, and does super uncool stuff.&lt;/p&gt;

&lt;p&gt;It would be much cooler if, instead of a single massive process, Firefox could use separate processes for content and chrome. Then, if a page crashes, at least the UI still works. And if we assign the content process(es) reduced permissions, we can keep possibly-jerkish content in a nice, safe sandbox so that it can’t do uncool things with our browser or computer.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Better performance, more security? Super cool.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Indeed. Separation is cool. &lt;a href=&quot;https://en.wikipedia.org/wiki/Electrolysis&quot;&gt;Electrolysis is separation&lt;/a&gt;. Ergo, Electrolysis is cool.&lt;/p&gt;

&lt;p&gt;It’s not perfect yet - for example, compatibility with right-to-left languages, accessibility (or “a11y”, if “e10s” needs a buddy), and add-ons is still an issue - but it’s getting there, and it’s rolling out real soon! Given that the project has been underway since 2008, that’s pretty exciting.&lt;/p&gt;

&lt;h2 id=&quot;rust-servo--oxidation&quot;&gt;Rust, Servo, &amp;amp; Oxidation&lt;/h2&gt;

&lt;p&gt;&lt;span style=&quot;float: right&quot;&gt; &lt;img src=&quot;https://www.rust-lang.org/logos/rust-logo-blk.svg&quot; alt=&quot;Rust logo&quot; /&gt; &lt;/span&gt;
I first heard about the increasingly popular language &lt;a href=&quot;https://www.rust-lang.org/&quot;&gt;Rust&lt;/a&gt; when I was at the &lt;a href=&quot;https://www.recurse.com&quot;&gt;Recurse Center&lt;/a&gt; last fall, and all I knew about it was that it was being used at Mozilla to develop a new browser engine called &lt;a href=&quot;https://servo.org/&quot;&gt;Servo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More recently, I heard talks from Mozillians like &lt;a href=&quot;http://conferences.oreilly.com/oscon/open-source-us/public/schedule/detail/49024&quot;&gt;E. Dunham&lt;/a&gt; that revealed a bit more about why people are so excited about Rust: it’s a new language for low-level programming, and compared with the current mainstay C, it guarantees memory safety. As in, “No more &lt;a href=&quot;https://en.wikipedia.org/wiki/Segmentation_fault&quot;&gt;segfaults&lt;/a&gt;, no more &lt;a href=&quot;https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/&quot;&gt;NULL&lt;/a&gt;s, no more &lt;a href=&quot;https://en.wikipedia.org/wiki/Dangling_pointer&quot;&gt;dangling pointers&lt;/a&gt;’ dirty looks”. It’s also been designed with &lt;a href=&quot;https://en.wikipedia.org/wiki/Concurrency_(computer_science)&quot;&gt;concurrency&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Thread_safety&quot;&gt;thread safety&lt;/a&gt; in mind, so that programs can take better advantage of e.g. multi-core processors. (Do not ask me to get into details on this; the lowest level I have programmed at is probably sitting in a beanbag chair. But I believe them when they say that Rust does those things, and that those things are good.)&lt;/p&gt;

&lt;p&gt;Finally, it has the advantage of having a tight-knit, active, and dedicated community &lt;a href=&quot;https://twitter.com/rustlang/status/633323561457971201&quot;&gt;“populated entirely by human beings”&lt;/a&gt;, which is due in no small part to the folks at Mozilla and beyond who’ve been working to &lt;a href=&quot;https://www.rust-lang.org/conduct.html&quot;&gt;keep the community that way&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;OK OK OK, so Rust is a super cool new language. What can you do with it?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, lots of stuff. For example, you could write a totally new &lt;a href=&quot;https://en.wikipedia.org/wiki/Web_browser_engine&quot;&gt;browser engine&lt;/a&gt;, and call it &lt;a href=&quot;https://servo.org/&quot;&gt;Servo&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Wait, what’s a browser engine?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A browser engine (aka layout or rendering engine) is basically the part of a browser that allows it to show you the web pages you navigate to. That is, it takes the raw HTML and CSS content of the page, figures out what it means, and turns it into a pretty picture for you to look at.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Uh, I’m pretty sure I can see web pages in Firefox right now. Doesn’t it already have an engine?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Indeed it does. It’s called &lt;a href=&quot;https://en.wikipedia.org/wiki/Gecko_(software)&quot;&gt;Gecko&lt;/a&gt;, and it’s written in C++. It lets Firefox make the web beautiful every day.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;So why Servo, then? Is it going to replace Gecko?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No. Servo is an experimental engine developed by Mozilla Research; it’s just intended to serve(-o!) as a playground for new ideas that could improve a browser’s performance and security.&lt;/p&gt;

&lt;p&gt;The beauty of having a research project like Servo and a real-world project like Gecko under the same roof at Mozilla is that when the Servo team’s research unveils some new and clever way of doing something faster or more awesomely than Gecko does, everybody wins! That’s thanks to the &lt;a href=&quot;https://wiki.mozilla.org/Oxidation&quot;&gt;Oxidation&lt;/a&gt; project, which aims to integrate clever Rust components cooked up in the Servo lab into Gecko. Apparently, Firefox 45 already got (somewhat unexpectedly) an MP4 metadata parser in Rust, which has been running just fine so far. It’s just the tip of the iceberg, but the potential for cool ideas from Servo to make their way into Gecko via Oxidation is pretty exciting.&lt;/p&gt;

&lt;h2 id=&quot;the-janitor&quot;&gt;The Janitor&lt;/h2&gt;

&lt;p&gt;Another really exciting thing I heard about during the week is &lt;a href=&quot;https://janitor.technology/&quot;&gt;The Janitor&lt;/a&gt;, a tool that lets you contribute to FOSS projects like Firefox straight from your browser.&lt;/p&gt;

&lt;p&gt;For me, one of the biggest hurdles to contributing to a new open-source project is getting the development environment all set up.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Ugh I hate that. I just want to change one line of code, do I really need to spend two days grappling with installation and configuration?!?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Exactly. But the Janitor to the rescue!&lt;/p&gt;

&lt;iframe src=&quot;//giphy.com/embed/XhLq1G1mvFpuM&quot; width=&quot;480&quot; height=&quot;257&quot; frameborder=&quot;0&quot; class=&quot;giphy-embed&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p style=&quot;font-size:.5em&quot;&gt;&lt;a href=&quot;http://giphy.com/gifs/perfectloops-spike-janitor-XhLq1G1mvFpuM&quot;&gt;Cowboy Bebop via GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Powered by the very cool &lt;a href=&quot;https://c9.io/&quot;&gt;Cloud9 IDE&lt;/a&gt;, the Janitor gives you one-click access to a ready-to-go, cloud-based development environment for a given project. At the moment there are a handful of project supported (including Firefox, Servo, and Google Chrome), and new ones can be added by simply writing a &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/docker-explained-using-dockerfiles-to-automate-building-of-images&quot;&gt;Dockerfile&lt;/a&gt;. I’m not sure that an easier point of entry for new FOSS contributors is physically possible. The ease of start-up is perfect for short-term contribution efforts like hackathons or workshops, and thanks to the collaborative features of Cloud9 it’s also perfect for remote pairing.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Awesome, I’m sold. How do I use it?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unfortunately, the Janitor is still in alpha and invite-only, but you can go to &lt;a href=&quot;https://janitor.technology&quot;&gt;janitor.technology&lt;/a&gt; and sign up to get on the waitlist. I’m still waiting to get my invite, but if it’s half as fantastic as it seems, it will be a huge step forward in making it easier for new contributors to get involved with FOSS projects. If it starts supporting offline work (apparently the Cloud9 editor is somewhat functional offline already, once you’ve loaded the page initially, but the terminal and VNC always needs a connection to function), I think it’ll be unstoppable.&lt;/p&gt;

&lt;h2 id=&quot;l20n&quot;&gt;L20n&lt;/h2&gt;

&lt;p&gt;The last cool thing I heard about (literally, it was the last session on Friday) at this work week was &lt;a href=&quot;http://l20n.org/&quot;&gt;L20n&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Wait, I thought “localization” was abbreviated “L10n”?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, um, that’s the whole pun. Way to be sharp, exhausted-from-a-week-of-talks-Anjana.&lt;/p&gt;

&lt;p&gt;See, L20n is a next-generation framework for web and browser localization (l10n) and internationalization (i18n). It’s apparently a long-running project too, born out of the frustrations of the l10n status quo.&lt;/p&gt;

&lt;p&gt;According to the L20n team, at the moment the localization system for Firefox is spread over multiple files with multiple syntaxes, which is no fun for localizers, and multiple APIs, which is no fun for developers. What we end up with is program logic intermingling with l10n/i18n decisions (say, determining the correct format for a date) such that developers, who probably aren’t also localizers, end up making decisions about language that should really be in the hands of the localizers. And if a localizer makes a syntax error when editing a certain localization file, the entire browser refuses to run. Not cool.&lt;/p&gt;

&lt;p&gt;Pop quiz: what’s cool?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Um…&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;C’mon, we just went over this. Go on and scroll up.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Electrolyis?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, that’s cool, but thinking more generally…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Separation?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s right! &lt;em&gt;Separation&lt;/em&gt; is super cool! And that’s what L20n does: separate l10n code from program source code. This way, developers aren’t pretending to be localizers, and localizers aren’t crashing browsers. Instead, developers are merely getting localized strings by calling a single L20n API, and localizers are providing localized strings in a single file format &amp;amp; syntax.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;Wait but, isn’t unifying everything into a single API/file format the opposite of separation? Does that mean it’s not cool?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Shhh. Meaningful separation of concerns is cool. Arbitrary separation of a single concern (l10n) is not cool. L20n knows the difference.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;OK, fine. But first “e10s” and “a11y”, now “l10n”/”l20n” and “i18n”… why does everything need a numbreviation?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You’ve got me there.&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">Last week, all of Mozilla met in London for a whirlwind tour from TARDIS to TaskCluster, from BBC1 to e10s, from Regent Park to the release train, from Paddington to Positron. As an Outreachy intern, I felt incredibly lucky to be part of this event, which gave me a chance to get to know Mozilla, my team, and the other interns much better. It was a jam-packed work week of talks, meetings, team events, pubs, and parties, and it would be impossible to blog about all of the fun, fascinating, and foxy things I learned and did. But I can at least give you some of the highlights! Or, should I say, Who-lights? (Be warned, that is not the last pun you will encounter here today.) Foxy, the TARDIS, and espionage in the park? All in a day&amp;#39;s work at #MozLondon! pic.twitter.com/QPWdPRnJHY&amp;mdash; Anjana Vakil (@AnjanaVakil) June 14, 2016</summary></entry><entry><title type="html">I want to mock with you</title><link href="http://anjana.dev/blog/i-want-to-mock-with-you/" rel="alternate" type="text/html" title="I want to mock with you" /><published>2016-06-16T00:00:00+00:00</published><updated>2016-06-16T00:00:00+00:00</updated><id>http://anjana.dev/blog/i-want-to-mock-with-you</id><content type="html" xml:base="http://anjana.dev/blog/i-want-to-mock-with-you/">&lt;p&gt;&lt;em&gt;This post brought to you from Mozilla’s London All Hands meeting - cheers!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When writing Python unit tests, sometimes you want to just test one specific aspect of a piece of code that does multiple things.&lt;/p&gt;

&lt;p&gt;For example, maybe you’re wondering:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Does object X get created here?&lt;/li&gt;
  &lt;li&gt;Does method X get called here?&lt;/li&gt;
  &lt;li&gt;Assuming method X returns Y, does the right thing happen after that?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finding the answers to such questions is super simple if you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt;: a library which “allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.” Since Python 3.3 it’s available simply as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest.mock&lt;/code&gt;, but if you’re using an earlier Python you can get it from PyPI with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install mock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, what are mocks? How do you use them?&lt;/p&gt;

&lt;p&gt;Well, in short I could tell you that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock&lt;/code&gt; is a sort of magical object that’s intended to be a doppelgänger for some object in your code that you want to test. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock&lt;/code&gt;s have special attributes and methods you can use to find out how your test is using the object you’re mocking. For example, you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock.called&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.call_count&lt;/code&gt; to find out if and how many times a method has been called. You can also manipulate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock&lt;/code&gt;s to simulate functionality that you’re not directly testing, but is necessary for the code you’re testing. For example, you can set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock.return_value&lt;/code&gt; to pretend that an function gave you some particular output, and make sure that the right thing happens in your program.&lt;/p&gt;

&lt;p&gt;But honestly, I don’t think I could give a better or more succinct overview of mocks than the &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html#quick-guide&quot;&gt;Quick Guide&lt;/a&gt;, so for a real intro you should go read that. While you’re doing that, I’m going to watch this fantastic Michael Jackson video:&lt;/p&gt;

&lt;div style=&quot;text-align:center; padding:1em;&quot;&gt;&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/5X-Mrc2l1d0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;Oh you’re back? Hi! So, now that you have a basic idea of what makes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock&lt;/code&gt;s super cool, let me share with you some of the tips/tips/trials/tribulations I discovered when starting to use them.&lt;/p&gt;

&lt;h2 id=&quot;patches-and-namespaces&quot;&gt;Patches and namespaces&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;tl;dr: Learn &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html#where-to-patch&quot;&gt;where to patch&lt;/a&gt; if you don’t want to be sad!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you import a helper module into a module you’re testing, the tested module gets its own namespace for the helper module. So if you want to mock a class from the helper module, you need to mock it &lt;em&gt;within the tested module’s namespace&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, let’s say I have a Super Useful &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helper&lt;/code&gt; module, which defines a class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass&lt;/code&gt; that is So Very Helpful:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# helper.py

class HelperClass():
    def __init__(self):
        self.name = &quot;helper&quot;
    def help(self):
        helpful = True
        return helpful
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And in the module I want to test, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tested&lt;/code&gt;, I instantiate the Incredibly Helpful &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass&lt;/code&gt;, which I imported from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helper.py&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# tested.py

from helper import HelperClass

def fn():
    h = HelperClass() # using tested.HelperClass
    return h.help()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, let’s say that it is Incredibly Important that I make sure that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass&lt;/code&gt; object is actually getting created in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tested&lt;/code&gt;, i.e. that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass()&lt;/code&gt; is being called. I can write a test module that patches &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass&lt;/code&gt;, and check the resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mock&lt;/code&gt; object’s &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.called&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;called&lt;/code&gt; property&lt;/a&gt;. But I have to be careful that I patch the right &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass&lt;/code&gt;! Consider &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_tested.py&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# test_tested.py

import tested

from mock import patch

# This is not what you want:
@patch('helper.HelperClass')
def test_helper_wrong(mock_HelperClass):
    tested.fn()
    assert mock_HelperClass.called # Fails! I mocked the wrong class, am sad :(

# This is what you want:
@patch('tested.HelperClass')
def test_helper_right(mock_HelperClass):
    tested.fn()
    assert mock_HelperClass.called # Passes! I am not sad :)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;OK great! If I patch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tested.HelperClass&lt;/code&gt;, I get what I want.&lt;/p&gt;

&lt;p&gt;But what if the module I want to test uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import helper&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;helper.HelperClass()&lt;/code&gt;, instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from helper import HelperClass&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HelperClass()&lt;/code&gt;? As in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tested2.py&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# tested2.py

import helper

def fn():
    h = helper.HelperClass()
    return h.help()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case, in my test for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tested2&lt;/code&gt; I need to patch the class with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch('helper.HelperClass')&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch('tested.HelperClass')&lt;/code&gt;. Consider &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_tested2.py&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# test_tested2.py

import tested2
from mock import patch

# This time, this IS what I want:
@patch('helper.HelperClass')
def test_helper_2_right(mock_HelperClass):
    tested2.fn()
    assert mock_HelperClass.called # Passes! I am not sad :)

# And this is NOT what I want!
# Mock will complain: &quot;module 'tested2' does not have the attribute 'HelperClass'&quot;
@patch('tested2.HelperClass')
def test_helper_2_right(mock_HelperClass):
    tested2.fn()
    assert mock_HelperClass.called
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Wonderful!&lt;/p&gt;

&lt;p&gt;In short: be careful of which namespace you’re patching in. If you patch whatever object you’re testing in the wrong namespace, the object that’s created will be the real object, not the mocked version. And that will make you confused and sad.&lt;/p&gt;

&lt;p&gt;I was confused and sad when I was trying to mock the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TestManifest.active_tests()&lt;/code&gt; function to test &lt;a href=&quot;https://dxr.mozilla.org/mozilla-central/source/testing/marionette/harness/marionette/runner/base.py#902&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BaseMarionetteTestRunner.add_test&lt;/code&gt;&lt;/a&gt;, and I was trying to mock it in the place it was defined, i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch('manifestparser.manifestparser.TestManifest.active_tests')&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead, I had to patch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TestManifest&lt;/code&gt; &lt;em&gt;within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;runner.base&lt;/code&gt; module&lt;/em&gt;, i.e. the place where it was actually being called by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_test&lt;/code&gt; function, i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch('marionette.runner.base.TestManifest.active_tests')&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So don’t be confused or sad, mock the thing &lt;em&gt;where it is used&lt;/em&gt;, not where it was defined!&lt;/p&gt;

&lt;h2 id=&quot;pretending-to-read-files-with-mock_open&quot;&gt;Pretending to read files with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_open&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;One thing I find particularly annoying is writing tests for modules that have to interact with files. Well, I guess I could, like, write code in my tests that creates dummy files and then deletes them, or (even worse) just put some dummy files next to my test module for it to use. But wouldn’t it be better if I could just skip all that and &lt;em&gt;pretend&lt;/em&gt; the files exist, and have whatever content I need them to have?&lt;/p&gt;

&lt;p&gt;It sure would! And that’s exactly the type of thing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt; is really helpful with. In fact, there’s even a helper called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_open&lt;/code&gt; that makes it super simple to pretend to read a file. All you have to do is patch the builtin &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open&lt;/code&gt; function, and pass in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_open(read_data=&quot;my data&quot;)&lt;/code&gt; to the patch to make the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open&lt;/code&gt; in the code you’re testing only &lt;em&gt;pretend&lt;/em&gt; to open a file with that content, instead of actually doing it.&lt;/p&gt;

&lt;p&gt;To see it in action, you can take a look at a (not necessarily great) little test I wrote that pretends to open a file and read some data from it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def test_nonJSON_file_throws_error(runner):
    with patch('os.path.exists') as exists:
        exists.return_value = True
        with patch('__builtin__.open', mock_open(read_data='[not {valid JSON]')):
            with pytest.raises(Exception) as json_exc:
                runner._load_testvars() # This is the code I want to test, specifically to be sure it throws an exception
    assert 'not properly formatted' in json_exc.value.message
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;gotchya-mocking-and-debugging-at-the-same-time&quot;&gt;Gotchya: Mocking and debugging at the same time&lt;/h2&gt;

&lt;p&gt;See that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch('os.path.exists')&lt;/code&gt; in the test I just mentioned? Yeah, that’s probably not a great idea. At least, I found it problematic.&lt;/p&gt;

&lt;p&gt;I was having some difficulty with a similar test, in which I was also patching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;os.path.exists&lt;/code&gt; to fake a file (though that wasn’t the part I was having problems with), so I decided to &lt;a href=&quot;https://pytest.org/latest/usage.html#setting-a-breakpoint-aka-set-trace&quot;&gt;set a breakpoint with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pytest.set_trace()&lt;/code&gt;&lt;/a&gt; to drop into the Python debugger and try to understand the problem. The debugger I use is &lt;a href=&quot;https://pypi.python.org/pypi/pdbpp/&quot;&gt;pdb++&lt;/a&gt;, which just adds some helpful little features to the default &lt;a href=&quot;https://docs.python.org/3/library/pdb.html&quot;&gt;pdb&lt;/a&gt;, like colors and &lt;a href=&quot;https://pypi.python.org/pypi/pdbpp/#sticky-mode&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sticky&lt;/code&gt; mode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So there I am, merrily debugging away at my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(Pdb++)&lt;/code&gt; prompt. But as soon as I entered the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch('os.path.exists')&lt;/code&gt; context, I started getting weird behavior in the debugger console: complaints about some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.fancycompleterrc.py&lt;/code&gt; file and certain commands not working properly.&lt;/p&gt;

&lt;p&gt;It turns out that at least one module pdb++ was using (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fancycompleter&lt;/code&gt;) was getting confused about file(s) it needs to function, because of checks for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;os.path.exists&lt;/code&gt; that were now all messed up thanks to my ill-advised &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;patch&lt;/code&gt;. This had me scratching my head for longer than I’d like to admit.&lt;/p&gt;

&lt;p&gt;What I still don’t understand (explanations welcome!) is why I still got this weird behavior when I tried to change the test to patch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'mymodule.os.path.exists'&lt;/code&gt; (where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mymodule.py&lt;/code&gt; contains &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import os&lt;/code&gt;) instead of just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'os.path.exists'&lt;/code&gt;. Based on what we saw about namespaces, I figured this would restrict the mock to only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mymodule&lt;/code&gt;, so that pdb++ and related modules would be safe - but it didn’t seem to have any effect whatsoever. But I’ll have to save that mystery for another day (and another post).&lt;/p&gt;

&lt;p&gt;Still, lesson learned: if you’re patching a commonly used function, like, say, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;os.path.exists&lt;/code&gt;, don’t forget that once you’re inside that mocked context, you no longer have access to the real function &lt;em&gt;at all&lt;/em&gt;! So keep an eye out, and mock responsibly!&lt;/p&gt;

&lt;h2 id=&quot;mock-the-night-away&quot;&gt;Mock the night away&lt;/h2&gt;

&lt;p&gt;Those are just a few of the things I’ve learned in my first few weeks of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt;ing. If you need some bedtime reading, check out these resources that I found helpful:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.toptal.com/python/an-introduction-to-mocking-in-python&quot;&gt;An intro to mocking in Python&lt;/a&gt; on Toptal&lt;/li&gt;
  &lt;li&gt;Mozilla dev Armen Z.G.’s &lt;a href=&quot;http://armenzg.blogspot.de/2016/04/improving-how-i-write-python-tests.html&quot;&gt;blog post on better Python tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m sure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt; has all kinds of secrets, magic, and superpowers I’ve yet to discover, but that gives me something to look forward to! If you have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt;-foo tips to share, just give me a shout on &lt;a href=&quot;https://twitter.com/intent/tweet?screen_name=AnjanaVakil&quot;&gt;Twitter&lt;/a&gt;!&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">When writing Python unit tests, sometimes you want to just test one specific aspect of a piece of code that does multiple things. For example, maybe you're wondering: * Does object X get created here? * Does method X get called here? * Assuming method X returns Y, does the right thing happen after that? Finding the answers to such questions is super simple if you use `mock`: a library which 'allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.' Let's talk about why `Mock`s are super cool, and some of the tips/tips/trials/tribulations I discovered when starting to use them.</summary></entry><entry><title type="html">Warming up to Mercurial</title><link href="http://anjana.dev/blog/warming-up-to-mercurial/" rel="alternate" type="text/html" title="Warming up to Mercurial" /><published>2016-06-03T00:00:00+00:00</published><updated>2016-06-03T00:00:00+00:00</updated><id>http://anjana.dev/blog/warming-up-to-mercurial</id><content type="html" xml:base="http://anjana.dev/blog/warming-up-to-mercurial/">&lt;p&gt;When it comes to &lt;a href=&quot;https://en.wikipedia.org/wiki/Version_control&quot;&gt;version control&lt;/a&gt;, I’m a &lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt; girl. I had to use &lt;a href=&quot;https://subversion.apache.org/&quot;&gt;Subversion&lt;/a&gt; a little bit for a project in grad school (not distributed == not so fun). But I had never touched &lt;a href=&quot;https://www.mercurial-scm.org/&quot;&gt;Mercurial&lt;/a&gt; until I decided to contribute to Mozilla’s &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt;, a testing tool for Firefox, for my &lt;a href=&quot;/blog/outreachy-what-how-why/&quot;&gt;Outreachy application&lt;/a&gt;. Mercurial is the &lt;a href=&quot;http://mozilla-version-control-tools.readthedocs.io/en/latest/hgmozilla/index.html&quot;&gt;main version control system&lt;/a&gt; for Firefox and Marionette development,&lt;sup id=&quot;a1&quot;&gt;&lt;a href=&quot;#f1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; so this gave me a great opportunity to start learning my way around the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg&lt;/code&gt;. Turns out it’s really close to Git, though there are some subtle differences that can be a little tricky. This post documents the basics and the trip-ups I discovered. Although there’s plenty of &lt;a href=&quot;https://www.mercurial-scm.org/wiki/UnderstandingMercurial&quot;&gt;other&lt;/a&gt; &lt;a href=&quot;https://www.mercurial-scm.org/wiki/GitConcepts&quot;&gt;info&lt;/a&gt;  &lt;a href=&quot;https://docs.python.org/devguide/gitdevs.html#mercurial-for-git-developers&quot;&gt;out&lt;/a&gt; &lt;a href=&quot;https://sny.no/hg&quot;&gt;there&lt;/a&gt;, I hope some of this might be helpful for others (especially other Gitters) using Mercurial or &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Introduction&quot;&gt;contributing to Mozilla code&lt;/a&gt; for the first time. Ready to heat things up? Let’s do this!&lt;/p&gt;

&lt;h2 id=&quot;getting-my-bearings-on-planet-mercury&quot;&gt;Getting my bearings on Planet Mercury&lt;/h2&gt;

&lt;p&gt;OK, so I’ve been working through the &lt;a href=&quot;http://areweeveryoneyet.org/onramp/desktop.html&quot;&gt;Firefox Onramp&lt;/a&gt; to install Mercurial (via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bootstrap&lt;/code&gt; script) and clone the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mozilla-central&lt;/code&gt; repository, i.e. the source code for Firefox. This is just like Git; all I have to do is:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg clone &amp;lt;repo&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Incidentally, I like to pronounce the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg&lt;/code&gt; command “hug”, e.g. “hug clone”. Warm fuzzies!)&lt;/p&gt;

&lt;p&gt;Cool, I’ve set foot on a new planet! …But where am I? What’s going on?&lt;/p&gt;

&lt;p&gt;Just like in Git, I can find out about the repo’s history with &lt;a href=&quot;https://www.selenic.com/hg/help/log&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg log&lt;/code&gt;&lt;/a&gt;. Adding some flags make this even more readable: I like to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--limit&lt;/code&gt; the number of changesets (change-whats? more on that later) displayed to a small number, and show the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--graph&lt;/code&gt; to see how changes are related. For example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg log --graph --limit 5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or, for short:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg log -Gl5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This outputs something like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@    changeset:   300339:e27fe24a746f
|\   tag:         tip
| ~  fxtree:      central
|    parent:      300125:718e392bad42
|    parent:      300338:8b89d98ce322
|    user:        Carsten &quot;Tomcat&quot; Book &amp;lt;cbook@mozilla.com&amp;gt;
|    date:        Fri Jun 03 12:00:06 2016 +0200
|    summary:     merge mozilla-inbound to mozilla-central a=merge
|
o  changeset:   300338:8b89d98ce322
|  user:        Jean-Yves Avenard &amp;lt;jyavenard@mozilla.com&amp;gt;
|  date:        Thu Jun 02 21:08:05 2016 +1000
|  summary:     Bug 1277508: P2. Add HasPendingDrain convenience method. r=kamidphish
|
o  changeset:   300337:9cef6a01859a
|  user:        Jean-Yves Avenard &amp;lt;jyavenard@mozilla.com&amp;gt;
|  date:        Thu Jun 02 20:54:33 2016 +1000
|  summary:     Bug 1277508: P1. Don't attempt to demux new samples while we're currently draining. r=kamidphish
|
o  changeset:   300336:f75d7afd686e
|  user:        Jean-Yves Avenard &amp;lt;jyavenard@mozilla.com&amp;gt;
|  date:        Fri Jun 03 11:46:36 2016 +1000
|  summary:     Bug 1277729: Ignore readyState value when reporting the buffered range. r=jwwang
|
o  changeset:   300335:71a44348d3b7
|  user:        Jean-Yves Avenard &amp;lt;jyavenard@mozilla.com&amp;gt;
~  date:        Thu Jun 02 17:14:03 2016 +1000
   summary:     Bug 1276184: [MSE] P3. Be consistent with types when accessing track buffer. r=kamidphish
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Great! Now what does that all mean?&lt;/p&gt;

&lt;h2 id=&quot;some-confusing-terminology&quot;&gt;Some (confusing) terminology&lt;/h2&gt;

&lt;h3 id=&quot;changesetsrevisions-and-their-identifiers&quot;&gt;Changesets/revisions and their identifiers&lt;/h3&gt;

&lt;p&gt;According to the official definition, a &lt;a href=&quot;https://www.mercurial-scm.org/wiki/ChangeSet&quot;&gt;&lt;strong&gt;changeset&lt;/strong&gt;&lt;/a&gt; is “an atomic collection of changes to files in a repository.” As far as I can tell, this is basically what I would call a &lt;em&gt;commit&lt;/em&gt; in Gitese. For now, that’s how I’m going to think of a changeset, though I’m sure there’s some subtle difference that’s going to come back to bite me later. Looking forward to it!&lt;/p&gt;

&lt;p&gt;Changesets are also called &lt;a href=&quot;https://www.mercurial-scm.org/wiki/Revision&quot;&gt;&lt;strong&gt;revisions&lt;/strong&gt;&lt;/a&gt; (because two names are better than one?), and each one has (confusingly) two identifying numbers: a local &lt;em&gt;revision number&lt;/em&gt; (a small integer), and a global &lt;em&gt;changeset ID&lt;/em&gt; (a 40-digit hexadecimal, more like Git’s commit IDs). These are what you see in the output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg log&lt;/code&gt; above in the format:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;changeset: &amp;lt;revision-number&amp;gt;:&amp;lt;changeset-ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For example,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;changeset:   300339:e27fe24a746f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;is the changeset with revision number 300339 (its number in &lt;em&gt;my copy of the repo&lt;/em&gt;) and changeset ID e27fe24a746f (its number &lt;em&gt;everywhere&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Why the confusing double-numbering? Well, &lt;a href=&quot;https://www.mercurial-scm.org/wiki/RevisionNumber&quot;&gt;apparently&lt;/a&gt; because revision numbers are “shorter to type” when you want to refer to a certain changeset locally on the command line; but since revision numbers only apply to your local copy of the repo and will “very likely” be different in another contributor’s local copy, you should only use changeset IDs when discussing changes with others. But on the command line I usually just copy-paste the hash I want, so length doesn’t really matter, so… I’m just going to ignore revision numbers and always use changeset IDs, OK Mercurial? Cool.&lt;/p&gt;

&lt;h3 id=&quot;branches-bookmarks-heads-and-the-tip&quot;&gt;Branches, bookmarks, heads, and the tip&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;I know Git! I know what a “branch” is!  &lt;em&gt;- Anjana, learning Mercurial&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeeeah, about that… Unfortunately, this term in Gitese is a &lt;a href=&quot;https://en.wikipedia.org/wiki/False_friend&quot;&gt;false friend&lt;/a&gt; of its Mercurialian equivalent.&lt;/p&gt;

&lt;p&gt;In the land of Gitania, when it’s time to start work on a new bug/feature, I make a new branch, giving it a feature-specific name; do a bunch of work on that branch, merging in master as needed; then merge the branch back into master whenever the feature is complete. I can make as many branches as I want, whenever I want, and give them whatever names I want.&lt;/p&gt;

&lt;p&gt;This is because in Git, a “branch” is basically just a pointer (a reference or “ref”) to a certain commit, so I can add/delete/change that pointer whenever and however I want without altering the commit(s) at all.  But on Mercury, a &lt;a href=&quot;https://www.mercurial-scm.org/wiki/Branch&quot;&gt;&lt;strong&gt;branch&lt;/strong&gt;&lt;/a&gt; is simply a “diverged” series of changesets; it comes to exist simply by virtue of a given changeset having multiple children, and it doesn’t need to have a name. In the output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg log --graph&lt;/code&gt;, you can see the branches on the left hand side: continuation of a branch looks like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt;, merging &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|\&lt;/code&gt;, and branching &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|/&lt;/code&gt;. &lt;a href=&quot;https://www.mercurial-scm.org/wiki/GraphlogExtension&quot;&gt;Here&lt;/a&gt; are some examples of what that looks like.&lt;/p&gt;

&lt;p&gt;Confusingly, Mercuial also has &lt;a href=&quot;https://www.mercurial-scm.org/wiki/NamedBranches&quot;&gt;&lt;strong&gt;named branches&lt;/strong&gt;&lt;/a&gt;, which are intended to be longer-lived than branches in Git, and actually become part of a commit’s information; when you make a commit on a certain named branch, that branch is part of that commit forever. &lt;a href=&quot;https://felipec.wordpress.com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/&quot;&gt;This post&lt;/a&gt; has a pretty good explanation of this.&lt;/p&gt;

&lt;p&gt;Luckily, Mercurial does have an equivalent to Git’s branches: they’re called &lt;a href=&quot;https://www.mercurial-scm.org/wiki/Bookmarks&quot;&gt;&lt;strong&gt;bookmarks&lt;/strong&gt;&lt;/a&gt;. Like Git branches, Mercurial bookmarks are just handy references to certain commits. I can create a new one thus:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg bookmark my-awesome-bookmark
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When I make it, it will point to the changeset I’m currently on, and if I commit more work, it will move forward to point to my most recent changeset. Once I’ve created a bookmark, I can use its name pretty much anywhere I can use a changeset ID, to refer to the changeset the bookmark is pointing to: e.g. to point to the bookmark I can do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg up my-awesome-bookmark&lt;/code&gt;. I can see all my bookmarks and the changesets they’re pointing to with the command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg bookmarks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which outputs something like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   loadvars                  298655:fe18ebae0d9c
   resetstats                300075:81795401c97b
 * my-awesome-bookmark       300339:e27fe24a746f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When I’m on a bookmark, it’s “active”; the currently active bookmark is indicated with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;OK, maybe I was wrong about branches, but at least I know what the “HEAD” is!  &lt;em&gt;- Anjana, a bit later&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, nope. I think of the “HEAD” in Git as the branch (or commit, if I’m in “detached HEAD” state) I’m currently on, i.e. a pointer to (the pointer to) the commit that would end up the parent of whatever I commit next. In Mercurial, this doesn’t seem to have a special name like “HEAD”, but it’s indicated in the output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg log --graph&lt;/code&gt; by the symbol &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@&lt;/code&gt;. However, Mercurial documentation does talk about &lt;a href=&quot;https://www.mercurial-scm.org/wiki/Head&quot;&gt;&lt;strong&gt;heads&lt;/strong&gt;&lt;/a&gt;, which are just the most recent changesets on all branches (regardless of whether those branches have names or bookmarks pointing to them or not).&lt;sup id=&quot;a2&quot;&gt;&lt;a href=&quot;#f2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; You can see all those with the command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg heads&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The head which is the most recent changeset, period, gets a special name: the &lt;a href=&quot;https://www.mercurial-scm.org/wiki/Head&quot;&gt;&lt;strong&gt;tip&lt;/strong&gt;&lt;/a&gt;. This is another slight difference from Git, where we can talk about “the tip of a branch”, and therefore have several tips. In Mercurial, there is only one. It’s labeled in the output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg log&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tag: tip&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;recap-mercurial-glossary&quot;&gt;Recap: Mercurial glossary&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Term&lt;/th&gt;
      &lt;th&gt;Meaning&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.mercurial-scm.org/wiki/Branch&quot;&gt;branch&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;a “diverged” series of changesets; doesn’t need to have a name&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.mercurial-scm.org/wiki/Bookmarks&quot;&gt;bookmark&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;a named reference to a given commit; can be used much like a Git branch&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.mercurial-scm.org/wiki/Head&quot;&gt;heads&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;the last changesets on each diverged branch, i.e. changesets which have no children&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;a href=&quot;https://www.mercurial-scm.org/wiki/Head&quot;&gt;tip&lt;/a&gt;&lt;/td&gt;
      &lt;td&gt;the most recent changeset in the entire history (regardless of branch structure)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;all-the-worlds-a-stage-but-mercurys-not-the-world&quot;&gt;All the world’s a stage (but Mercury’s not the world)&lt;/h2&gt;

&lt;p&gt;Just like with Git, I can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg status&lt;/code&gt; to see the changes I’m about to commit before committing with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg commit&lt;/code&gt;. However, what’s missing is the part where it tells me which changes are &lt;em&gt;staged&lt;/em&gt;, i.e. “to be committed”. Turns out the concept of “staging” is unique to Git; Mercurial doesn’t have it. That means that when you type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg commit&lt;/code&gt;, any changes to any tracked files in the repo will be committed; you don’t have to manually stage them like you do with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add &amp;lt;file&amp;gt;&lt;/code&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg add &amp;lt;file&amp;gt;&lt;/code&gt; is only used to tell Mercurial to track a new file that it’s not tracking yet).&lt;/p&gt;

&lt;p&gt;However, just like you can use &lt;a href=&quot;/blog/git-add-patch/&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add --patch&lt;/code&gt;&lt;/a&gt; to stage individual changes to a certain file a la carte, you can use the now-standard &lt;a href=&quot;https://www.mercurial-scm.org/wiki/RecordExtension&quot;&gt;record extension&lt;/a&gt; to commit only certain files or parts of files at a time with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg commit --interactive&lt;/code&gt;. I haven’t yet had occasion to use this myself, but I’m looking forward to it!&lt;/p&gt;

&lt;h2 id=&quot;turning-back-time&quot;&gt;Turning back time&lt;/h2&gt;

&lt;p&gt;I can mess with my Mercurial history in almost exactly the same way as I would in Git, although whereas this functionality is built in to Git, in Mercurial it’s accomplished by means of extensions. I can use the &lt;a href=&quot;https://www.mercurial-scm.org/wiki/RebaseExtension&quot;&gt;rebase extension&lt;/a&gt; to rebase a series of changesets (say, the parents of the active bookmark location) onto a given changeset (say, the latest change I pulled from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;central&lt;/code&gt;) with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg rebase&lt;/code&gt;, and I can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg histedit&lt;/code&gt; command provided by the &lt;a href=&quot;https://www.mercurial-scm.org/wiki/HisteditExtension&quot;&gt;histedit extension&lt;/a&gt; to reorder, edit, and squash (or “fold”, to use the Mercurialian term) changesets like I would with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase --interactive&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;my-mozilla-workflow&quot;&gt;My Mozilla workflow&lt;/h2&gt;

&lt;p&gt;In my &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1275269&quot;&gt;recent work&lt;/a&gt; refactoring and adding unit tests for &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt;’s Python test runner, I use a workflow that goes something like this.&lt;/p&gt;

&lt;p&gt;I’m gonna start work on a new bug/feature, so first I want to make a new bookmark for work that will branch off of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;central&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg up central
$ hg bookmark my-feature
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now I go ahead and do some work, and when I’m ready to commit it I simply do:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg commit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which opens my default editor so that I can write a super great commit message. It’s going to be informative and &lt;a href=&quot;http://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview/commits.html#formatting-commit-messages-to-influence-behavior&quot;&gt;formatted properly&lt;/a&gt; for &lt;a href=&quot;http://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview.html&quot;&gt;MozReview&lt;/a&gt;/&lt;a href=&quot;https://bugzilla.mozilla.org/&quot;&gt;Bugzilla&lt;/a&gt;, so it might look something like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Bug 1275269 - Add tests for _add_tests; r?maja_zf

Add tests for BaseMarionetteTestRunner._add_tests:
Test that _add_tests populates self.tests with correct tests;
Test that invalid test names cause _add_tests to
throw Exception and report invalid names as expected.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After working for a while, it’s possible that some new changes have come in on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;central&lt;/code&gt; (this happens about daily), so I may need to rebase my work on top of them. I can do that with:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg pull central
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;followed by:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg rebase -d central
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which rebases the commits in the branch that my bookmark points to onto the most recent changeset in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;central&lt;/code&gt;. Note that this assumes that the bookmark I want to rebase is currently active (I can check if it is with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg bookmarks&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Then maybe I commit some more work, so that now I have a series of commits on my bookmark. But perhaps I want to reorder them, squash some together, or edit commit messages; no problemo, I just do a quick:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg histedit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which opens a &lt;a href=&quot;https://www.mercurial-scm.org/wiki/HisteditExtension#line-1-3&quot;&gt;history&lt;/a&gt; listing all the changesets on my bookmark. I can edit that file to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pick&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fold&lt;/code&gt; (squash), or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;edit&lt;/code&gt; changesets in pretty much the same way I would using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase --interactive&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When I’m satisfied with the history, I &lt;a href=&quot;http://mozilla-version-control-tools.readthedocs.io/en/latest/mozreview/commits.html#submitting-commits-for-review&quot;&gt;push my changes to review&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hg push review
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;My special Mozillian configuration of Mercurial, which a wizard helped me set up during &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Mercurial/Installing_Mercurial&quot;&gt;installation&lt;/a&gt;, magically prepares everything for MozReview and then asks me if I want to&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;publish these review requests now (Yn)?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To which I of course say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt; (or, you know, realize I made a horrible mistake, say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt;, go back and re-do everything, and then push to review again).&lt;/p&gt;

&lt;p&gt;Then I just wait for review feedback from my mentor, and perhaps make some changes and amend my commits based on that feedback, and push those to review again.&lt;/p&gt;

&lt;p&gt;Ultimately, once the review has passed, my changes get merged into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mozilla-inbound&lt;/code&gt;, then eventually &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mozilla-central&lt;/code&gt; (more on what that all means in a future post), and I become an official contributor. Yay! :)&lt;/p&gt;

&lt;h2 id=&quot;so-is-this-goodbye-git&quot;&gt;So is this goodbye Git?&lt;/h2&gt;

&lt;p&gt;Nah, I’ll still be using Git as my go-to version control system for my own projects, and another Mozilla project I’m contributing to, &lt;a href=&quot;https://wiki.mozilla.org/EngineeringProductivity/Projects/Perfherder&quot;&gt;Perfherder&lt;/a&gt;, has its code on &lt;a href=&quot;https://github.com/mozilla/treeherder&quot;&gt;Github&lt;/a&gt;, so Git is the default for that.&lt;/p&gt;

&lt;p&gt;But learning to use Mercurial, like learning any new tool, has been educational! Although my progress was (and still is) a bit slow as I get used to the differences in features/workflow (which, I should reiterate, are quite minor when coming from Git), I’ve learned a bit more about version control systems in general, and some of the design decisions that have gone into these two. Plus, I’ve been able to contribute to a great open-source project! I’d call that a win. Thanks Mercurial, you deserve a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hg&lt;/code&gt;. :)&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.mercurial-scm.org/wiki/UnderstandingMercurial&quot;&gt;Understanding Mercurial&lt;/a&gt; and &lt;a href=&quot;https://www.mercurial-scm.org/wiki/GitConcepts&quot;&gt;Mercurial for Git users&lt;/a&gt; on the Mercurial wiki&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.python.org/devguide/gitdevs.html&quot;&gt;Mercurial for git developers&lt;/a&gt; from the Python Developer’s Guide&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://sny.no/hg&quot;&gt;Mercurial Tips&lt;/a&gt; from Mozilla developer Andreas Tolfsen (:ato)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://felipec.wordpress.com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/&quot;&gt;Mercurial vs Git; it’s all in the branches&lt;/a&gt; by Felipe Contreras&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;notes&quot;&gt;Notes&lt;/h4&gt;

&lt;p&gt;&lt;b id=&quot;f1&quot;&gt;1&lt;/b&gt; However, there is a small but ardent faction of Mozilla devs who refuse to stop using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Git&quot;&gt;Git&lt;/a&gt;. Despite being a Gitter, I chose to forego this option and use Mercurial because a) it’s the default, so most of the documentation etc. assumes it’s what you’re using, and b) I figured it was a good chance to get to know a new tool. &lt;a href=&quot;#a1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b id=&quot;f2&quot;&gt;2&lt;/b&gt; Git actually uses this term the same way; the tips of all branches are stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git/refs/heads&lt;/code&gt;. But in my experience the term “heads” doesn’t pop up as often in Git as in Mercurial. Maybe this is because in Git we can talk about “branches” instead? &lt;a href=&quot;#a2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">When it comes to version control, I’m a Git girl. I had to use Subversion a little bit for a project in grad school (not distributed == not so fun). But I had never touched Mercurial until I decided to contribute to Mozilla’s Marionette, a testing tool for Firefox, for my Outreachy application. Mercurial is the main version control system for Firefox and Marionette development,1 so this gave me a great opportunity to start learning my way around the hg. Turns out it’s really close to Git, though there are some subtle differences that can be a little tricky. This post documents the basics and the trip-ups I discovered. Although there’s plenty of other info out there, I hope some of this might be helpful for others (especially other Gitters) using Mercurial or contributing to Mozilla code for the first time. Ready to heat things up? Let’s do this!</summary></entry><entry><title type="html">Outreachy: What? How? Why?</title><link href="http://anjana.dev/blog/outreachy-what-how-why/" rel="alternate" type="text/html" title="Outreachy: What? How? Why?" /><published>2016-05-23T00:00:00+00:00</published><updated>2016-05-23T00:00:00+00:00</updated><id>http://anjana.dev/blog/outreachy-what-how-why</id><content type="html" xml:base="http://anjana.dev/blog/outreachy-what-how-why/">&lt;p&gt;Today was my first day as an &lt;a href=&quot;https://gnome.org/outreachy&quot;&gt;Outreachy&lt;/a&gt; intern with &lt;a href=&quot;https://www.mozilla.org&quot;&gt;Mozilla&lt;/a&gt;! What does that even mean? Why is it super exciting? How did I swing such a sweet gig? How will I be spending my summer non-vacation? Read on to find out!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.gnome.org/outreachy&quot;&gt;&lt;img src=&quot;https://outreachy.gnome.org/skins/easterngreen/css/img/outreachy-logo.png&quot; alt=&quot;Outreachy logo&quot; title=&quot;Outreachy logo (outreachy.gnome.org)&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;what-is-outreachy&quot;&gt;What is Outreachy?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://gnome.org/outreachy&quot;&gt;Outreachy&lt;/a&gt; is a fantastic initiative to get more women and members of other underrepresented groups involved in Free &amp;amp; Open Source Software. Through Outreachy, organizations that create open-source software (e.g. &lt;a href=&quot;https://www.mozilla.org/Outreachy&quot;&gt;Mozilla&lt;/a&gt;, &lt;a href=&quot;https://wiki.gnome.org/Outreach/Outreachy&quot;&gt;GNOME&lt;/a&gt;, &lt;a href=&quot;https://www.mediawiki.org/wiki/Outreachy/Round_12&quot;&gt;Wikimedia&lt;/a&gt;, to name a few) take on interns to work full-time on a specific project for 3 months. There are two internship rounds each year, May-August and December-March. Interns are paid for their time, and receive guidance/supervision from an assigned mentor, usually a full-time employee of the organization who leads the given project.&lt;/p&gt;

&lt;p&gt;Oh yeah, and the whole thing is done remotely! For a lot of people (myself included) who don’t/can’t/won’t live in a major tech hub, the opportunity to work remotely removes one of the biggest barriers to jumping in to the professional tech community. But as FOSS developers tend to be pretty distributed anyway (I think my project’s team, for example, is on about 3 continents), it’s relatively easy for the intern to integrate with the team. It seems that most communication takes place over  &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Getting_Started_with_IRC&quot;&gt;IRC&lt;/a&gt; and, to a lesser extent, videoconferencing.&lt;/p&gt;

&lt;h2 id=&quot;what-does-an-outreachy-intern-do&quot;&gt;What does an Outreachy intern do?&lt;/h2&gt;

&lt;p&gt;Anything and everything! Each project and organization is different. But in general, interns spend their time…&lt;/p&gt;

&lt;h4 id=&quot;coding-or-not&quot;&gt;Coding (or not)&lt;/h4&gt;
&lt;p&gt;A lot of projects involve writing code, though what that actually entails (language, framework, writing vs. refactoring, etc.) varies from organization to organization and project to project. However, there are also projects that don’t involve code at all, and instead have the intern working on equally important things like design, documentation, or community management.&lt;/p&gt;

&lt;p&gt;As for me specifically, I’ll be working on the project &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner_.5Bno_longer_taking_applicants.5D&quot;&gt;Test-driven Refactoring of Marionette’s Python Test Runner&lt;/a&gt;. You can click through to the project description for more details, but basically I’ll be spending most of the summer writing Python code (yay!) to test and refactor a component of  &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt;, a tool that lets developers run automated Firefox tests. This means I’ll be learning a lot about testing in general, Python testing libraries, the huge ecosystem of internal Mozilla tools, and maybe a bit about browser automation. That’s a lot! Luckily, I have my mentor Maja (who happens to also be an alum of both Outreachy and RC!) to help me out along the way, as well as the other members of the Engineering Productivity team, all of whom have been really friendly &amp;amp; helpful so far.&lt;/p&gt;

&lt;h4 id=&quot;traveling&quot;&gt;Traveling&lt;/h4&gt;
&lt;p&gt;Interns receive a $500 stipend for travel related to Outreachy, which is fantastic. I intend, as I’m guessing most do, to use this to attend conference(s) related to open source. If I were doing a winter round I would totally use it to attend &lt;a href=&quot;https://fosdem.org&quot;&gt;FOSDEM&lt;/a&gt;, but there are also a ton of conferences in the summer! Actually, you don’t even need to do the traveling during the actual 3 months of the internship; they give you a year-long window so that if there’s an annual conference you really want to attend but it’s not during your internship, you’re still golden.&lt;/p&gt;

&lt;p&gt;At Mozilla in particular, interns are also invited to a week-long all-hands meet up! This is beyond awesome, because it gives us a chance to meet our mentors and other team members in person. (Actually, I doubly lucked out because I got to meet my mentor at RC during “Never Graduate Week” a couple of weeks ago!)&lt;/p&gt;

&lt;h4 id=&quot;blogging&quot;&gt;Blogging&lt;/h4&gt;
&lt;p&gt;One of the requirements of the internship is to blog regularly about how the internship and project are coming along. This is my first post! Though we’re required to write a post every 2 weeks, I’m aiming to write one per week, on both technical and non-technical aspects of the internship. Stay tuned!&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-get-in&quot;&gt;How do you get in?&lt;/h2&gt;

&lt;p&gt;I’m sure every Outreachy participant has a different journey, but here’s a rough outline of mine.&lt;/p&gt;

&lt;h4 id=&quot;step-1-realize-it-is-a-thing&quot;&gt;Step 1: Realize it is a thing&lt;/h4&gt;
&lt;p&gt;Let’s not forget that the first step to applying for any program/job/whatever is realizing that it exists! Like most people, I think, I had never heard of Outreachy, and was totally unaware that a remote, paid internship working on FOSS was a thing that existed in the universe. But then, in the fall of 2015, I made one of my all-time best moves ever by attending the &lt;a href=&quot;https://www.recurse.com&quot;&gt;Recurse Center&lt;/a&gt; (RC), where I soon learned about Outreachy from various Recursers who had been involved with the program. I discovered it about 2 weeks before applications closed for the December-March 2015-16 round, which was pretty last-minute; but a couple of other Recursers were applying and encouraged me to do the same, so I decided to go for it!&lt;/p&gt;

&lt;h4 id=&quot;step-2-frantically-apply-at-last-minute&quot;&gt;Step 2: Frantically apply at last minute&lt;/h4&gt;
&lt;p&gt;Applying to Outreachy is a relatively involved &lt;a href=&quot;https://wiki.gnome.org/Outreachy#Application_Process&quot;&gt;process&lt;/a&gt;. A couple months before each round begins, the list of participating organizations/projects is released. Prospective applicants are supposed to find a project that interests them, get in touch with the project mentor, and make an initial contribution to that project (e.g. fix a small bug).&lt;/p&gt;

&lt;p&gt;But each of those tasks is pretty intimidating!&lt;/p&gt;

&lt;p&gt;First of all, the list of participating organizations is long and varied, and some organizations (like Mozilla) have tons of different projects available. So even reading through the project descriptions and choosing one that sounds interesting (most of them do, at least to me!) is no small task.&lt;/p&gt;

&lt;p&gt;Then, there’s the matter of mustering up the courage to join the organization/project’s IRC channel, find the project mentor, and talk to them about the application. I didn’t even really know what IRC was, and had never used it before, so I found this pretty scary. Luckily, I was RC, and one of my batchmates sat me down and walked me through IRC basics.&lt;/p&gt;

&lt;p&gt;However, the hardest and most important part is actually making a contribution to the project at hand. Depending on the project, this can be long &amp;amp; complicated, quick &amp;amp; easy, or anything in between. The level of guidance/instruction also varies widely from project to project: some are laid out clearly in small, hand-holdy steps, others are more along the lines of “find something to do and then do it”. Furthermore, prerequisites for making the contribution can be anything from “if you know how to edit text and send an email, you’re fine” to “make a GitHub account” to “learn a new programming language and install 8 million new tools on your system just to set up the development environment”. All in all, this means that making that initial contribution can often be a deceptively large amount of work.&lt;/p&gt;

&lt;p&gt;Because of all these factors, for my application to the December-March round I decided to target the Mozilla project “Contribute to the HTML standard”. In addition to the fact that I thought it would be awesome to contribute to such a fundamental part of the web, I chose it because the contribution itself was really simple: just choose a GitHub issue with a beginner-friendly label, ask some questions via GitHub comments, edit the source markup file as needed, and make a pull request. I was already familiar with GitHub so it was pretty smooth sailing.&lt;/p&gt;

&lt;p&gt;Once you’ve made your contribution, it’s time to write the actual Outreachy application. This is just a &lt;a href=&quot;https://wiki.gnome.org/Outreachy#Application_Form&quot;&gt;plain text file&lt;/a&gt; you fill out with lots of information about your experience with FOSS, your contribution to the project, etc. In case it’s useful to anyone, here’s &lt;a href=&quot;https://docs.google.com/document/d/1jgMBJeqTzgcYlSVOz_QQlz1w2coNy5m0H59XLmoTYM0/edit?usp=sharing&quot;&gt;my application&lt;/a&gt; for the December-March 2015-16 round. But before you use that as an example, make sure you read what happened next…&lt;/p&gt;

&lt;h4 id=&quot;step-3-dont-get-in&quot;&gt;Step 3: Don’t get in&lt;/h4&gt;

&lt;p&gt;Unfortunately, I didn’t get in to the December-March round (although I was stoked to see some of my fellow Recursers get accepted!). Honestly, I wasn’t too surprised, since my contributions and application had been so hectic and last-minute. But even though it wasn’t successful, the application process was educational in and of itself: I learned how to use IRC, got 3 of my first 5 GitHub pull requests merged, and became a &lt;a href=&quot;https://html.spec.whatwg.org/multipage/acknowledgements.html&quot;&gt;contributor to the HTML standard&lt;/a&gt;! Not bad for a failure!&lt;/p&gt;

&lt;h4 id=&quot;step-4-decide-to-go-for-it-again-at-last-minute-again&quot;&gt;Step 4: Decide to go for it again (at last minute, again)&lt;/h4&gt;

&lt;p&gt;Fast forward six months: after finishing my batch at RC, I had been looking &amp;amp; interview-prepping, but still hadn’t gotten a job. When the applications for the May-August round opened up, I took a glance at the projects and found some cool ones, but decided that I wouldn’t apply this round because a) I needed a Real Job, not an internship, and b) the last round’s application process was a pretty big time investment which hadn’t paid off (although it actually had, as I just mentioned!).&lt;/p&gt;

&lt;p&gt;But as the weeks went by, and the application deadline drew closer, I kept thinking about it. I was no closer to finding a Real Job, and upheaval in my personal life made my whereabouts over the summer an uncertainty (I seem never to know what continent I live on), so a paid, remote internship was becoming more and more attractive. When I broached my hesitation over whether or not to apply to other Recursers, they unanimously encouraged me (again) to go for it (again). Then, I found out that one of the project mentors, Maja, was a Recurser, and since her project was one of the ones I had shortlisted, I decided to apply for it.&lt;/p&gt;

&lt;p&gt;Of course, by this point it was once again two weeks until the deadline, so panic once again set in!&lt;/p&gt;

&lt;h4 id=&quot;step-5-learn-from-past-mistakes&quot;&gt;Step 5: Learn from past mistakes&lt;/h4&gt;

&lt;p&gt;This time, the process as a whole was easier, because I had already done it once. IRC was less scary, I already felt comfortable asking the project mentor questions, and having already been rejected in the previous round made it somehow lower-stakes emotionally (“What the hell, at least I’ll get a PR or two out of it!”). During my first application I had spent a considerable amount of time reading about all the different projects and fretting about which one to do, flipping back and forth mentally until the last minute. This time, I avoided that mistake and was laser-focused on a single project: &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner_.5Bno_longer_taking_applicants.5D&quot;&gt;Test-driven Refactoring of Marionette’s Python Test Runner&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From a technical standpoint, however, contributing to the Marionette project was more complicated than the HTML standard had been. Luckily, Maja had written detailed instructions for prospective applicants explaining how to set up the development environment etc., but there were still a lot of steps to work through. Then, because there were so many folks applying to the project, there was actually a shortage of “good-first-bugs” for &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette&quot;&gt;Marionette&lt;/a&gt;! So I ended up making my first contributions to a different but related project, &lt;a href=&quot;https://wiki.mozilla.org/EngineeringProductivity/Projects/Perfherder&quot;&gt;Perfherder&lt;/a&gt;, which meant setting up a different dev environment and working with a different mentor (who was equally friendly). By the time I was done with the Perfherder stuff (which turned out to be a fun little rabbit hole!), Maja had found me something Marionette-specific to do, so I ended up working on both projects as part of my application process.&lt;/p&gt;

&lt;p&gt;When it came time to write the actual application, I also had the luxury of being able to use my &lt;a href=&quot;&quot;&gt;failed December-March application&lt;/a&gt; as both a starting point and an example of what not to do. Some of the more generic parts (my background, etc.) were reusable, which saved time. But when it came to the parts about my contribution to the project and my proposed internship timeline, I knew I had to do a much better job than before. So I opted for over-communciation, and basically wrote down everything I could think of about what I had already done and what I would need to do to complete the goals stated in the &lt;a href=&quot;https://wiki.mozilla.org/Outreachy#Test-driven_Refactoring_of_Marionette.27s_Python_Test_Runner_.5Bno_longer_taking_applicants.5D&quot;&gt;project description&lt;/a&gt; (which Maja had thankfully written quite clearly).&lt;/p&gt;

&lt;p&gt;In the end, my &lt;a href=&quot;https://docs.google.com/document/d/1HJAzL-1WgjvikB-4TQlMadiQDa6wI7CIY2HaIIc0mPI/edit?usp=sharing&quot;&gt;May-August application&lt;/a&gt; was twice as long as my previous one had been. Much of that difference was the proposed timeline, which went from being one short paragraph to about 3 pages. Perhaps I was a bit more verbose than necessary, but I decided to err on the side of too many details, since I had done the opposite in my previous application.&lt;/p&gt;

&lt;h4 id=&quot;step-6-get-a-bit-lucky&quot;&gt;Step 6: Get a bit lucky&lt;/h4&gt;

&lt;p&gt;Spoiler alert: this time I was accepted!&lt;/p&gt;

&lt;p&gt;Although I knew I had made a much stronger application than in the previous round, I was still shocked to find out that I was chosen from what seemed to be a large, competitive applicant pool. I can’t be sure, but I think what made the difference the second time around must have been a) more substantial contributions to two different projects, b) better, more frequent communication with the project mentor and other team members, and c) a much more thorough and better thought-out application text.&lt;/p&gt;

&lt;p&gt;But let’s not forget d) luck. I was lucky to have encouragement and support from the RC community throughout both my applications, lucky to have the time to work diligently on my application because I had no other full-time obligations, lucky to find a mentor who I had something in common with and therefore felt comfortable talking to and asking questions of, and lucky to ultimately be chosen from among what I’m sure were many strong applications. So while I certainly did work hard to get this internship, I have to acknowledge that I wouldn’t have gotten in without all of that luck.&lt;/p&gt;

&lt;h2 id=&quot;why-am-i-doing-this&quot;&gt;Why am I doing this?&lt;/h2&gt;

&lt;p&gt;Last week I had the chance to attend &lt;a href=&quot;http://conferences.oreilly.com/oscon/open-source-us&quot;&gt;OSCON 2016&lt;/a&gt;, where Mozilla’s &lt;a href=&quot;http://edunham.net/&quot;&gt;E. Dunham&lt;/a&gt; gave a talk on &lt;a href=&quot;http://conferences.oreilly.com/oscon/open-source-us/public/schedule/detail/49024&quot;&gt;How to learn Rust&lt;/a&gt;. A lot of the information applied to learning any language/new thing, though, including this great recommendation: When embarking on a new skill quest, record your motivation somewhere (I’m going to use this blog, but I suppose Twitter or a vision board or whatever would work too) before you begin.&lt;/p&gt;

&lt;p&gt;The idea is that once you’re in the process of learning the new thing, you will probably have at least one moment where you’re stuck, frustrated, and asking yourself what the hell you were thinking when you began this crazy project. Writing it down beforehand is just doing your future self a favor, by saving up some motivation for a rainy day.&lt;/p&gt;

&lt;p&gt;So, future self, let it be known that I’m doing Outreachy to…&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Write code for an actual real-world project (as opposed to academic/toy projects that no one will ever use)&lt;/li&gt;
  &lt;li&gt;Get to know a great organization that I’ve respected and admired for years&lt;/li&gt;
  &lt;li&gt;Try out working remotely, to see if it suits me&lt;/li&gt;
  &lt;li&gt;Learn more about Python, testing, and automation&lt;/li&gt;
  &lt;li&gt;Gain confidence and feel more like a “real developer”&lt;/li&gt;
  &lt;li&gt;Launch my career in the software industry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m sure these goals will evolve as the internship goes along, but for now they’re the main things driving me. Now it’s just a matter of sitting back, relaxing, and working super hard all summer to achieve them! :D&lt;/p&gt;

&lt;h2 id=&quot;got-any-more-questions&quot;&gt;Got any more questions?&lt;/h2&gt;

&lt;p&gt;Are you curious about Outreachy? Thinking of applying? Confused about the application process? Feel free to reach out to me! Go on, don’t be shy, just use one of those cute little contact buttons and drop me a line. :)&lt;/p&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><category term="outreachy" /><summary type="html">Today was my first day as an Outreachy intern with Mozilla! What does that even mean? Why is it super exciting? How did I swing such a sweet gig? How will I be spending my summer non-vacation? Read on to find out!</summary></entry><entry><title type="html">Notes from JSUnconf 2016</title><link href="http://anjana.dev/blog/notes-from-jsunconf-2016/" rel="alternate" type="text/html" title="Notes from JSUnconf 2016" /><published>2016-04-24T00:00:00+00:00</published><updated>2016-04-24T00:00:00+00:00</updated><id>http://anjana.dev/blog/notes-from-jsunconf-2016</id><content type="html" xml:base="http://anjana.dev/blog/notes-from-jsunconf-2016/">&lt;p&gt;This conference was awesome: not too big, not too cramped of a schedule (long breaks between talk sessions), free drinks, snacks &amp;amp; meals (with vegan options!), unisex bathrooms (toiletries &amp;amp; tampons provided!), a code of conduct, and - most importantly, to me - a great diversity program that gave me and 16 others support to attend! The unconference format was really interesting, and worked better than I expected. It also enabled something I wasn’t planning on: I gave my first talk at a tech conference!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://lh3.googleusercontent.com/Rv61ltt_JFagIWXMhlIf2Rf50pczPaG2BOvobHh-KaT4nQr-pzbdyjeEFKdRl29xgVQ2OWThkk_jkHJE_jRGmA_JtR8lClFAaLPnhWN401ZU14H5yN_7Zvy5vNvypJ70skD2Lz_sYRG3znRfLD-qdev7f0pJ5QvX25Jk7Q20z9MwwISSzI23XLYtcs2-1q3Lfc_itY5zQQ6iUk4oQmz8TQg-Bas1d3BSMrF9cg6wLpLBX53UTLt-EpmStaID5ZAmxhOdXbJ4aDjIyc5lm-eRKx5TWsgIHQ7HWOfFysipLQ9Mt6LT2rXLv-olCg9mlM41HhUy8VX20Hkcp-QU7ftp5afYhttQrQ6NhciY9C2tNuCgij3H5P7Dat6ufjALey5Cp3jKKaJV2FydTdQW8B6-9boyUvLdsnBvvDhdcpoFEI9441CTcfdmHUs5BHvfykEr6KZdCNPncWv-QQj_ymDcc1i5PGxAlWg9XU6lw0ZnrzCNxlEUK_VRG-LYgTzjWJXQl6RNglI5vsjiBAvJAZwNGw4ErBS3Nw-vCbIqB-ZOfnzL0W83Ndmc8uO4DpRkDIaHwX3XVFIsr3CsVN6s8Nyc8ave83ypUHA=w1158-h772-no&quot; alt=&quot;A photo of a large purple footstool with the JSUnconf logo next to a reusable JSUnconf coffee cup, with the walking feet of a conference attendee visible in the background&quot; title=&quot;On the ground at JSUnconf&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;whats-an-unconference&quot;&gt;What’s an unconference?&lt;/h2&gt;

&lt;p&gt;There’s no pre-planned schedule; instead, at the beginning of each day, anyone who’s interested in giving a talk makes a short pitch of their topic, and for the next hour or so the rest of the attendees vote on which talks they want to attend. The highest-voted talks are selected, and begin shortly after that. It sounds like it would be chaos, but it works!&lt;/p&gt;

&lt;h2 id=&quot;i-gave-my-first-tech-talk-on-3-hours-notice&quot;&gt;I gave my first tech talk! On 3 hours’ notice!&lt;/h2&gt;

&lt;p&gt;On day 2 of the conference, in a completely unexpected turn of events, I proposed, planned, and delivered a 30-minute talk within a period of about 3 hours. Am I crazy? Perhaps. But the good kind of crazy!&lt;/p&gt;

&lt;p&gt;See, there had been some interest in functional programming in JS (as part of the unconference format, people can submit topics they’d like to &lt;em&gt;hear&lt;/em&gt; a talk on as well), and some talks on specific topics related to functional languages/libraries, but no one had proposed a high-level general introduction about it. So, at literally the last minute of the talk-proposal session, I spontaneously got up and pitched “Learning Functional Programming with JS” (that’s how I learned FP, after all!).&lt;/p&gt;

&lt;p&gt;Turns out people were indeed interested: my proposal actually got more votes than any other that day. Which meant that I would present in the main room, the only one out of the three tracks that was being recorded. So all I had to do was, you know, plan a talk and make slides from scratch and then speak for 30 minutes in front of a camera, all in the space of about 3 hours.&lt;/p&gt;

&lt;p&gt;Yay! No, wait… panic!&lt;/p&gt;

&lt;p&gt;Luckily my years of teaching experience and a few presentations at academic conferences came to the rescue. I had to skip a couple of the sessions before mine (luckily some talks were recorded), and get a little instant feedback from a few folks at the conference that I had gotten to know, but ultimately I was able to throw together a talk outline and some &lt;a href=&quot;https://slidr.io/vakila/learning-functional-programming-with-javascript&quot;&gt;slides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When it came to actually delivering the talk, it was actually less scary than I thought. I even had enough time to do an ad-hoc digression (on the chalkboard!!!) into persistent data structures, which are the topic of my first &lt;em&gt;scheduled&lt;/em&gt; tech talk at &lt;a href=&quot;http://bangbangcon.com/speakers.html#anjana-vakil&quot;&gt;!!Con 2016&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, how did it go? I’ll let Twitter tell you:&lt;/p&gt;

&lt;div style=&quot;max-width: 60%; margin: 0px auto;&quot;&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;And now: Learning functional programming with JS and &lt;a href=&quot;https://twitter.com/AnjanaVakil&quot;&gt;@AnjanaVakil&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/jsunconf?src=hash&quot;&gt;#jsunconf&lt;/a&gt; 💡 &lt;a href=&quot;https://t.co/2CzOJ5JID0&quot;&gt;pic.twitter.com/2CzOJ5JID0&lt;/a&gt;&lt;/p&gt;&amp;mdash; Nina (@sssggr) &lt;a href=&quot;https://twitter.com/sssggr/status/724214727631638528&quot;&gt;April 24, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;!-- &lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt; --&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Is it a bird? 🐦 No! Plane? ✈ Nope, it&amp;#39;s a Mapreduce Sandwich! 🍔&lt;a href=&quot;https://twitter.com/AnjanaVakil&quot;&gt;@AnjanaVakil&lt;/a&gt;&amp;#39;s 💯 intro to functional prog. &lt;a href=&quot;https://twitter.com/hashtag/jsunconf?src=hash&quot;&gt;#jsunconf&lt;/a&gt; &lt;a href=&quot;https://t.co/uqUniJ4zpg&quot;&gt;pic.twitter.com/uqUniJ4zpg&lt;/a&gt;&lt;/p&gt;&amp;mdash; Flaki (@slsoftworks) &lt;a href=&quot;https://twitter.com/slsoftworks/status/724219910897950720&quot;&gt;April 24, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Back 2 School with &lt;a href=&quot;https://twitter.com/AnjanaVakil&quot;&gt;@AnjanaVakil&lt;/a&gt; and Functional Programming in JS ! &lt;a href=&quot;https://twitter.com/jsunconf&quot;&gt;@jsunconf&lt;/a&gt; Awesome talk ! &lt;a href=&quot;https://twitter.com/hashtag/jsunconf?src=hash&quot;&gt;#jsunconf&lt;/a&gt; &lt;a href=&quot;https://t.co/xa4oHYlE68&quot;&gt;pic.twitter.com/xa4oHYlE68&lt;/a&gt;&lt;/p&gt;&amp;mdash; claudiahdz ᕕ( ᐛ )ᕗ (@koste4) &lt;a href=&quot;https://twitter.com/koste4/status/724221656286257152&quot;&gt;April 24, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;One of the best talks of &lt;a href=&quot;https://twitter.com/hashtag/jsunconf?src=hash&quot;&gt;#jsunconf&lt;/a&gt; by &lt;a href=&quot;https://twitter.com/AnjanaVakil&quot;&gt;@AnjanaVakil&lt;/a&gt; &amp;amp; a good reason why DiversitySupport improves the DevCommunity 👍 &lt;a href=&quot;https://t.co/I1YgHc5Vs9&quot;&gt;pic.twitter.com/I1YgHc5Vs9&lt;/a&gt;&lt;/p&gt;&amp;mdash; Robert  Willemelis (@robertSPD) &lt;a href=&quot;https://twitter.com/robertSPD/status/724223007212761088&quot;&gt;April 24, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;Aw geez y’all, I’m blushing! :D&lt;/p&gt;

&lt;p&gt;The whole thing was a great experience, and definitely gave me a huge confidence boost for speaking at more conferences in the future (look out, &lt;a href=&quot;http://bangbangcon.com/speakers.html#anjana-vakil&quot;&gt;!!Con&lt;/a&gt; and &lt;a href=&quot;https://ep2016.europython.eu/conference/p/-958&quot;&gt;EuroPython&lt;/a&gt;!). I would recommend it to anyone! Come to think of it, &lt;a href=&quot;https://speakerdeck.com/sheley/why-arent-you-giving-talks-yet-jsunconf2016&quot;&gt;why aren’t you giving talks yet?&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;some-things-i-learned-at-jsunconf&quot;&gt;Some things I learned at JSUnconf&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The unconference format is pretty sweet!&lt;/li&gt;
  &lt;li&gt;Giving a tech talk is not as scary as all that!&lt;/li&gt;
  &lt;li&gt;HTTP/2 is a thing&lt;/li&gt;
  &lt;li&gt;Service Workers are a thing&lt;/li&gt;
  &lt;li&gt;There is a library for building neural nets in JS: &lt;a href=&quot;http://synaptic.juancazala.com/#/&quot;&gt;Synaptic&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;I want to learn Elm&lt;/li&gt;
  &lt;li&gt;Flora Power Mate is so much better than Club Mate (i.e. it actually tastes like mate)!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;talk-notes&quot;&gt;Talk notes&lt;/h2&gt;

&lt;p&gt;These are the unedited notes I jotted down during the talks. Mistakes, omissions, and misunderstandings are totally possible! Don’t take my word for anything; when in doubt check out the &lt;a href=&quot;https://docs.google.com/spreadsheets/d/1UztwJ7g-R0L6WznNF6JYWwamMsChZeAL_VV2qyrSe8o/edit#gid=0&quot;&gt;slides&lt;/a&gt;!&lt;/p&gt;

&lt;h3 id=&quot;http2&quot;&gt;HTTP/2&lt;/h3&gt;

&lt;p&gt;Speaker: Ole Michaelis (@CodeStars, nesQuick on Github), from Jimdo&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HTTP/1.1 has been in use since 1997&lt;/li&gt;
  &lt;li&gt;But it has some problems:
    &lt;ul&gt;
      &lt;li&gt;Lots of requests required to load a single page; “request bonanza”&lt;/li&gt;
      &lt;li&gt;Have to load the page itself, assets, ad stuff, tracking stuff….&lt;/li&gt;
      &lt;li&gt;Requests have to be done one-at-a-time, creating a “‘waterfall’ of blocked requests”&lt;/li&gt;
      &lt;li&gt;This causes latency (e.g. ~10 second load time for a web page like The Verge)&lt;/li&gt;
      &lt;li&gt;Especially problematic for mobile&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;You can get around it with weird hacks/workarounds, but these could violate best practices&lt;/li&gt;
  &lt;li&gt;Google made a thing called SPDY (“speedy”), which was sort of a predecessor to…&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://http2.github.io/faq/&quot;&gt;HTTP/2&lt;/a&gt; is the real solution
    &lt;ul&gt;
      &lt;li&gt;Binary, not text&lt;/li&gt;
      &lt;li&gt;Single TCP connection, but multiple streams with requests running in parallel&lt;/li&gt;
      &lt;li&gt;Headers are compressed&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Each browser can determine how to figure out/build the tree of dependencies
    &lt;ul&gt;
      &lt;li&gt;Firefox has the most efficient implementation at the moment&lt;/li&gt;
      &lt;li&gt;It sets up the dependency tree of requests before actually making any requests (?)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Sidenote: Huffman encoding
    &lt;ul&gt;
      &lt;li&gt;Take a string to compress&lt;/li&gt;
      &lt;li&gt;Count the frequencies of each character&lt;/li&gt;
      &lt;li&gt;Make a binary tree such that the leaf nodes are the characters arranged left-to-right from most frequent to least, and the leaves are connected through binary nodes from right to left, where each branch is labeled 0 on the left and 1 on the right&lt;/li&gt;
      &lt;li&gt;Use the path from the root of the tree to the character’s leaf node as the compression table&lt;/li&gt;
      &lt;li&gt;So the most frequent character will be 00, the least frequent will be e.g. 1111&lt;/li&gt;
      &lt;li&gt;This means more frequent characters have shorter compressions, so the overall compression will be as small as possible&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;HTTP/2 is already in use (22% of sites(???)) - you should start using it now!
    &lt;ul&gt;
      &lt;li&gt;Customers using HTTP/1.1 will experience an increase in load times, but those using updated browsers will see a decrease&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;natural-user-interfaces-using-js&quot;&gt;Natural user interfaces using JS&lt;/h3&gt;

&lt;p&gt;Speaker: @princi_ya, from Zalando&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Gesture-based interfaces, e.g. Intel RealSense 3D, Leap Motion&lt;/li&gt;
  &lt;li&gt;Some terminology:
    &lt;ul&gt;
      &lt;li&gt;Augmented Reality, also called Mediated Reality(?): real environment augmented with virtual components&lt;/li&gt;
      &lt;li&gt;Virtual Reality: totally simulated environment&lt;/li&gt;
      &lt;li&gt;Perceptual Computing: automatically perceiving what’s happening in the environment&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Using JS/the browser to communicate with RealSense/Leap Motion SDK via WebSocket server and getUserMedia to access the user’s webcam&lt;/li&gt;
  &lt;li&gt;JS-Object Detect - open-source library for object detection from webcam&lt;/li&gt;
  &lt;li&gt;Unfortunately not very accurate - demo didn’t work&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;elm-web-development-with-delight&quot;&gt;Elm: Web development with delight&lt;/h3&gt;

&lt;p&gt;Speaker: Bastian Krol (@bastiankrol), from codecentric&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://basti1302.github.io/talks/2016_jsunconf_hh_elm/index.html#/&quot;&gt;Slides&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Why Elm?
    &lt;ul&gt;
      &lt;li&gt;Clean syntax - inspired by Haskell(?) and OCaml&lt;/li&gt;
      &lt;li&gt;No runtime exceptions (!!!) - if code compiles, it will run&lt;/li&gt;
      &lt;li&gt;Interoperates smoothly with vanilla JS, you can use JS libraries&lt;/li&gt;
      &lt;li&gt;Reduces bug hunting&lt;/li&gt;
      &lt;li&gt;Everything is stateless &amp;amp; immutable
        &lt;ul&gt;
          &lt;li&gt;application is composed out of stateless functions&lt;/li&gt;
          &lt;li&gt;removes a whole category of bugs in JS&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Hello world:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import Html
main = Html.text &quot;Hello Hamburg!&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Convention: every Elm app has a “main” module, and that module has a “main” function&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Optional type annotations (best practice to add type annotations to all your top-level functions):
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  import Html exposing (Html)

  greet : Int -&amp;gt; String -&amp;gt; Html
  greet number string =
    Html.text str

  main : Html
  main =
    greet &quot;Hello Hamburg&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Elm supports partial function application
    &lt;ul&gt;
      &lt;li&gt;when it takes in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Int&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet&lt;/code&gt; function above, it essentially returns an anonymous function that takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String&lt;/code&gt; and returns an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Html&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;so there’s no real difference between
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet : Int -&amp;gt; String -&amp;gt; Html&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet : Int -&amp;gt; (String -&amp;gt; Html)&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Signals
    &lt;ul&gt;
      &lt;li&gt;use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Signal.map&lt;/code&gt; to do something with the input from the signal (e.g. map &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mouse.x&lt;/code&gt; to Html)&lt;/li&gt;
      &lt;li&gt;can filter signals do drop certain events if you’re not interested&lt;/li&gt;
      &lt;li&gt;you can also&lt;/li&gt;
      &lt;li&gt;Further reading:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;http://elm-lang.org/guide/reactivity&quot;&gt;Elm guide to reactivity&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;Elm architecture tutorial&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Architecture
    &lt;ul&gt;
      &lt;li&gt;Features:
        &lt;ul&gt;
          &lt;li&gt;Unidirectional data flow&lt;/li&gt;
          &lt;li&gt;Single source of truth&lt;/li&gt;
          &lt;li&gt;Everything immutable &amp;amp; stateless&lt;/li&gt;
          &lt;li&gt;…these are similar to Redux and other popular libraries (who may have copied these features from Elm)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Uniform structure for apps&lt;/li&gt;
      &lt;li&gt;Main concepts:
        &lt;ul&gt;
          &lt;li&gt;Model: custom type that you declare (could be a simple int or a huge data structure)&lt;/li&gt;
          &lt;li&gt;Update: function that takes an action and the current model, and produces a new model (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Action -&amp;gt; Model -&amp;gt; Model&lt;/code&gt;)&lt;/li&gt;
          &lt;li&gt;View: function that turns a model into an Html structure (essentially how you render the model)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Compiler
    &lt;ul&gt;
      &lt;li&gt;Catches edge cases etc., e.g. empty lists&lt;/li&gt;
      &lt;li&gt;So if your code compiles it will run - no runtime errors!&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;shipping-an-app-to-production-using-webmidi-and-webaudio-lessons-learned&quot;&gt;Shipping an app to production using WebMIDI and WebAudio: Lessons learned&lt;/h3&gt;

&lt;p&gt;Speaker: Jan Krutisch&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Web Audio API
    &lt;ul&gt;
      &lt;li&gt;allows you to generate, play back, modify, filter, etc. digital sounds/music of any sort in a flexible way&lt;/li&gt;
      &lt;li&gt;can build synthesizers with it, use audio in your games, etc. etc.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Web MIDI API
    &lt;ul&gt;
      &lt;li&gt;MIDI: Musical Instrument Digital Interface&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Weird bit operations in JS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;some-experiences-building-an-android-app-with-react-native--redux&quot;&gt;Some experiences building an Android app with React Native &amp;amp; Redux&lt;/h3&gt;

&lt;p&gt;Speaker: Alex Bepple (@alexbepple), from &lt;a href=&quot;http://it-agile.de&quot;&gt;it-agile&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Introducing a new term: Owdaf - One-way reactive data flow (aka unidirectional data flow)&lt;/li&gt;
  &lt;li&gt;What’s cool about Owdaf?
    &lt;ul&gt;
      &lt;li&gt;All UI is a functional representation of the state of the (web/mobile/whatever) app&lt;/li&gt;
      &lt;li&gt;The user always sees the same thing if the state is the same&lt;/li&gt;
      &lt;li&gt;Changing what the user sees requires dispatching an action - but the presentational components don’t need to know anything about that&lt;/li&gt;
      &lt;li&gt;You change something in one place, and everything in UI gets updated automatically&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;React Native
    &lt;ul&gt;
      &lt;li&gt;Bridge between JS and the UI&lt;/li&gt;
      &lt;li&gt;You have native components for the given mobile platform, but they’re controlled from a JS thread&lt;/li&gt;
      &lt;li&gt;Great &lt;a href=&quot;http://js.coach/react-native&quot;&gt;ecosystem of components&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Some gotchyas: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;require&lt;/code&gt; is different than in node, problems centering a grid, …&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Redux:
    &lt;ul&gt;
      &lt;li&gt;brings Owdaf to React Native (?)&lt;/li&gt;
      &lt;li&gt;can persist state using redux-storage library&lt;/li&gt;
      &lt;li&gt;can use libraries like redux-act to create actions and reducers&lt;/li&gt;
      &lt;li&gt;encapsulation is a problem (?)&lt;/li&gt;
      &lt;li&gt;there’s supposed to be time-traveling, but it didn’t work last he checked&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;React Native &amp;amp; Redux together:
    &lt;ul&gt;
      &lt;li&gt;Biggest gotchya: how to represent navigation in your global state?&lt;/li&gt;
      &lt;li&gt;for regular React there is react-router-redux&lt;/li&gt;
      &lt;li&gt;no such thing for React Native (because the concept of a URL doesn’t really exist in a native app)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Anjana Sofia Vakil</name><email>contact@anjana.dev</email></author><summary type="html">This conference was awesome: not too big, not too cramped of a schedule (long breaks between talk sessions), free drinks, snacks &amp;amp; meals (with vegan options!), unisex bathrooms (toiletries &amp;amp; tampons provided!), a code of conduct, and - most importantly, to me - a great diversity program that gave me and 16 others support to attend! The unconference format was really interesting, and worked better than I expected. It also enabled something I wasn’t planning on: I gave my first talk at a tech conference!</summary></entry></feed>