<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ahmed Al-Obaidi</title>
    <description>The latest articles on Forem by Ahmed Al-Obaidi (@muubar).</description>
    <link>https://forem.com/muubar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F34356%2F9c95bd9f-1768-44b6-8bb5-793521c6abd7.png</url>
      <title>Forem: Ahmed Al-Obaidi</title>
      <link>https://forem.com/muubar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/muubar"/>
    <language>en</language>
    <item>
      <title>Developing critical software: Intro to formal methods and theorem provers</title>
      <dc:creator>Ahmed Al-Obaidi</dc:creator>
      <pubDate>Wed, 27 May 2020 15:48:35 +0000</pubDate>
      <link>https://forem.com/muubar/developing-critical-software-intro-to-formal-methods-and-theorem-provers-1bn1</link>
      <guid>https://forem.com/muubar/developing-critical-software-intro-to-formal-methods-and-theorem-provers-1bn1</guid>
      <description>&lt;p&gt;The amount and complexity of software developed and used has grown tremendously. There are many applications where high reliability must be ensured, because failures are costly (with respect to human lives, environmental issues, or money).&lt;br&gt;
There are more safety-critical software systems than you realize, but they don’t get nearly as much attention as consumer-focused software, and it can be found in almost all areas, e.g., aviation, (nuclear) power plants, medicine, transportation, space technologies, process control, and banking.&lt;br&gt;
Whereas the crash of a word processor or your favorite game may be a nuisance, a malfunction in software controlling a nuclear plant could possibly cost thousands of human lives, and could put millions more at risk; recent actual examples of critical systems failing would be &lt;a href="https://en.wikipedia.org/wiki/Boeing_737_MAX_groundings"&gt;Boeing’s 737 MAX groundings&lt;/a&gt;, and the &lt;a href="https://meltdownattack.com/"&gt;“Meltdown and Spectre” Vulnerabilities&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety first
&lt;/h2&gt;

&lt;p&gt;In most companies, software developers are primarily concerned with shipping more features, and delivering more value. But software developers involved in the creation of safety-critical systems must be concerned primarily with creating safe systems. And that is a very different task.&lt;br&gt;
Most safety-critical software appears to be developed using the &lt;a href="https://www.tutorialspoint.com/sdlc/sdlc_waterfall_model.htm"&gt;waterfall&lt;/a&gt; or &lt;a href="https://www.tutorialspoint.com/sdlc/sdlc_spiral_model.htm"&gt;spiral&lt;/a&gt; models. NASA specifically recommends against using &lt;a href="https://resources.collab.net/agile-101/agile-methodologies"&gt;Agile&lt;/a&gt; methods for the safety-critical components in &lt;a href="https://standards.nasa.gov/standard/nasa/nasa-gb-871913"&gt;its software guidebook&lt;/a&gt; (page 87)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fg2JWRxw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jygmuwwehfnc4sr7e2f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fg2JWRxw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/jygmuwwehfnc4sr7e2f5.png" alt="defects per thousand lines of code vs. dependability of multiple systems" width="880" height="668"&gt;&lt;/a&gt;&lt;/p&gt;
Defects per thousand lines of code vs. dependability of multiple systems, the goal here is to show how "different" critical systems are



&lt;h2&gt;
  
  
  The problem with testing:
&lt;/h2&gt;

&lt;p&gt;The most common way to check for faults and bugs is to use &lt;a href="https://www.geeksforgeeks.org/software-testing-basics/"&gt;testing&lt;/a&gt;, and &lt;a href="https://smartbear.com/learn/code-review/what-is-code-review/"&gt;human review&lt;/a&gt;. During and after the implementation of the system, the system’s functionality is usually tested to ensure that the resulting program satisfies the &lt;a href="https://en.wikipedia.org/wiki/Software_requirements"&gt;requirements&lt;/a&gt; and that no errors or bugs are present. Testing large and complex systems can be very time consuming and, due to the size of the system and the amount of code, an exhaustive testing is practically impossible. Nevertheless, when the system is safety and security critical, correct functionality must be guaranteed, which requires either exhaustive testing or a way of proving that the code correctly implements the specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formal methods:
&lt;/h2&gt;

&lt;p&gt;In computer science, &lt;a href="https://en.wikipedia.org/wiki/Formal_methods"&gt;formal methods&lt;/a&gt; are mathematically rigorous techniques and tools for the &lt;a href="https://en.wikipedia.org/wiki/Software_requirements_specification"&gt;specification&lt;/a&gt;, design and &lt;a href="https://en.wikipedia.org/wiki/Software_verification"&gt;verification&lt;/a&gt; of software and hardware Systems. Mathematically rigorous means that the specification consists of Well-formed statements using &lt;a href="https://en.wikipedia.org/wiki/Mathematical_logic"&gt;mathematical logic&lt;/a&gt; and that a formal verification consists of rigorous deductions in that logic. A formal specification is precise and there is no risk of misinterpretations. Also, if there is a proof that the implementation abides by the specification, then one can be sure that the programmers have implemented what is described in the specification, which means complete verification of the entire &lt;a href="https://en.wikipedia.org/wiki/State-space_representation"&gt;state space&lt;/a&gt; of the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OeDDpjIT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hv23lk38rfdj6ti5nqvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OeDDpjIT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hv23lk38rfdj6ti5nqvh.png" alt='a basic banking system specification using the "Z" formal specification language' width="880" height="561"&gt;&lt;/a&gt;&lt;/p&gt;
A basic banking system specification using the "Z" formal specification language



&lt;p&gt;When formal methods cannot be used through the entire development process (due to the complexity of the system, lack of tools or other reasons), they can still be used successfully on parts of the system, for example on the most safety or security critical components alone.&lt;/p&gt;

&lt;p&gt;Formal methods are used in several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To assure the software after-the-fact.&lt;/li&gt;
&lt;li&gt;To assure the software in parallel.&lt;/li&gt;
&lt;li&gt;To develop the software.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“After the fact” software verification can increase the confidence in a safety-critical system. When the regular software development is completed, then the formal specification and verification begin. The software assurance engineer converts the “human readable” requirements into a formal specification and proves properties about the specification. The code that implements the system may also be formally verified in order to comply with the formal specification. With this approach, two separate development activities occur, increasing costs and schedule length. In addition, problems found at this late stage are costly to fix.&lt;/p&gt;

&lt;p&gt;“In parallel” software verification still uses two separate teams (software development and FM verification), but they operate in parallel during the whole process. The development team uses the regular practices of good software development. At the same time the FM team writes and verifies the formal system specifications. While still costly, this method of assuring the software allows for quicker development. Software errors are detected earlier in the development cycle when they are less expensive to correct. However, communication between the two teams is crucial for this approach to work.&lt;/p&gt;

&lt;p&gt;Instead of having two teams working in parallel, the software can be developed using FM exclusively. This is an integrated approach. Requirements and design are written in a formal language. The design is formally verified before code is generated. This method is the least costly of the three, though the developers must be trained in FM for it to work.&lt;/p&gt;

&lt;p&gt;Most formal methods are considered to be too clumsy and time-consuming in their application. They usually require a long learning curve for the software engineer and are often incompatible with the "as-we-always-did" software development procedures. Together with schedules, which are generally very tight, an application of formal methods in an industrial environment is often not accepted by the project team. This is where theorem provers can help.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interactive theorem provers
&lt;/h2&gt;

&lt;p&gt;By &lt;a href="https://en.wikipedia.org/wiki/Proof_assistant"&gt;interactive theorem proving&lt;/a&gt;, we mean some arrangement where the machine and a human user work together interactively to produce a &lt;a href="https://en.wikipedia.org/wiki/Formal_proof"&gt;formal proof&lt;/a&gt;.  There is a wide spectrum of possibilities.  At one extreme, the computer may act merely as a checker on a detailed formal proof produced by a human; at the other the prover may be highly automated and powerful, while nevertheless being subject to some degree of human guidance.&lt;br&gt;
ITPs can be customized to specific application domains by providing&lt;br&gt;
libraries of tactics, thus increasing the amount of automatic processing.&lt;br&gt;
On the other hand, interactive theorem provers have several serious disadvantages: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they can sometimes become “too interactive”, Even the smallest steps in the proof must be carried out by hand. &lt;/li&gt;
&lt;li&gt;Large and complicated proofs take weeks to months to be completed.&lt;/li&gt;
&lt;li&gt;most interactive theorem provers can only be used by people who have a lot of knowledge and experience in the application domain, the calculus, and sometimes even the implementation language of the prover, Therefore, the use of interactive theorem provers requires specially trained and experienced people.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wg3-t5bW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ul2l29wvq5i0yphtlzus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wg3-t5bW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ul2l29wvq5i0yphtlzus.png" alt="Isabelle, an interactive theorem prover" width="880" height="637"&gt;&lt;/a&gt;&lt;/p&gt;
Isabelle, an interactive theorem prover



&lt;h2&gt;
  
  
  Automated theorem provers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Automated_theorem_proving"&gt;Automated theorem provers&lt;/a&gt; are programs which, given a formula, try to evaluate whether the formula is universally valid. Currently, most ATPs are like racing cars: although very fast and powerful, they can’t be used for everyday traffic, because essential things (like headlights) are missing. The classical architecture of ATPs must be extended to several directions in order to be useful for real applications.&lt;br&gt;
Automated theorem provers are not a universal cure for every application and every proof obligation, even if they could be processed by the prover; In many cases, user interactions will always be necessary to perform complex core proof operations, However, the goal is to relieve the user from tedious low-level detail-work. Ideally, automated theorem provers can play a role in software engineering equivalent to a pocket calculator in classical engineering: simple tasks are done automatically, but there is still work to be done by the engineer.&lt;br&gt;
Another problem with automated theorem provers is that, in most cases, there is no user interface, and no possibility of debugging a formula. Current implementations expect a syntactically correct formula, and they provide no feedback if no proof can be found.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://theoremprover-museum.github.io/"&gt;The theorem prover museum&lt;/a&gt; is an initiative to conserve the sources of theorem prover systems for future analysis, since they are important scientific artifacts. It has the sources of many of the theorem provers.&lt;/p&gt;

&lt;h2&gt;
  
  
  examples of practical use:
&lt;/h2&gt;

&lt;p&gt;Formal methods have been successfully used on NASA, military, and commercial systems that were considered safety-critical applications, and interactive theorem provers such as &lt;a href="https://isabelle.in.tum.de/"&gt;Isabelle&lt;/a&gt; are being used successfully in verification of compilers, protocols, hardware, and algorithms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://sel4.systems/About/"&gt;seL4 micro-kernel&lt;/a&gt; has been formally verified from its abstract specification down to its C implementation using machine checking. The correctness of a very detailed, low-level design is shown, and the C implementation is formally verified. &lt;br&gt;
An abstract specification of the system was created as an operational model of the system. Then the &lt;a href="https://en.wikipedia.org/wiki/Haskell_(programming_language)"&gt;Haskell programming language&lt;/a&gt; was used to implement a prototype of the kernel. This prototype could be automatically translated into the theorem prover Isabelle to form an executable, design-level specification of the kernel. Then the mode was manually implemented in C to form a high-performance C implementation of seL4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AMD, Intel and others use automated theorem proving to verify that &lt;a href="https://en.wikipedia.org/wiki/Floating-point_arithmetic"&gt;division and other operations&lt;/a&gt; are correctly implemented in their processors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Lightweight_Java"&gt;Lightweight Java&lt;/a&gt; programming language was designed for academic purposes within the Computer Laboratory of university of Cambridge. it was proven type-sound using Isabelle.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://link.springer.com/content/pdf/10.1007%2F978-3-662-22646-9.pdf"&gt;J. Schumann, Automated Theorem Proving in Software Engineering, Springer, 2001&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.foi.se/rest-api/report/FOI-R--4156--SE"&gt;I. Rodhe, M. Karresand, Overview of formal methods in software engineering, 2015&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cl.cam.ac.uk/~jrh13/papers/joerg.pdf"&gt;J. Harrison, J. Urban, F. Wiedijk, History Of Interactive Theorem Proving&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://standards.nasa.gov/standard/nasa/nasa-gb-871913"&gt;NASA Software Safety Guidebook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://smallbusinessprogramming.com/safety-critical-software-15-things-every-developer-should-know/"&gt;B. Osepchuk, Safety-Critical Software: 15 things every developer should know, 2020&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>development</category>
    </item>
    <item>
      <title>Retaining what you learn, and developing your mental models (feat. Anki)</title>
      <dc:creator>Ahmed Al-Obaidi</dc:creator>
      <pubDate>Sat, 22 Feb 2020 23:56:43 +0000</pubDate>
      <link>https://forem.com/muubar/retaining-what-you-learn-and-developing-your-mental-models-feat-anki-1g67</link>
      <guid>https://forem.com/muubar/retaining-what-you-learn-and-developing-your-mental-models-feat-anki-1g67</guid>
      <description>&lt;p&gt;&lt;em&gt;This post mainly targets software developers; however, the practices presented are already being applied with success by medical students, and people learning new languages as well.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The problem:
&lt;/h1&gt;

&lt;p&gt;When I first started learning software development fundamentals a few years ago, I used to learn so much by simply reading or watching anything related to software development, and what made me learn even more is the fact that I’m a person who likes digging holes, if an article mentions a concept that I don’t know, I would go and find another article that explains that concept, but that blog post introduces yet another concept and I have to find out about that, and so on and so forth until I have 17 tabs open and I don’t remember where I came from anymore; during that period, I was focusing on &lt;a href="https://hired.com/blog/candidates/balance-breadth-depth-learning-software-development/" rel="noopener noreferrer"&gt;broadening my knowledge&lt;/a&gt;; I felt bad because I knew I won’t be able to retain all this as I wasn’t necessary going to regularly use all of it anytime soon.&lt;/p&gt;

&lt;h1&gt;
  
  
  The solution:
&lt;/h1&gt;

&lt;p&gt;I started using &lt;a href="https://apps.ankiweb.net/docs/manual.html#introduction" rel="noopener noreferrer"&gt;Anki&lt;/a&gt;; it's basically a &lt;a href="https://en.wikipedia.org/wiki/Flashcard" rel="noopener noreferrer"&gt;flashcards&lt;/a&gt; program, you simply create cards, and the program will handle the rest, it knows when you should review each card to successfully retain the information on that specific card, it's based on &lt;a href="https://en.wikipedia.org/wiki/Active_recall" rel="noopener noreferrer"&gt;active recalling&lt;/a&gt;, and &lt;a href="https://www.gwern.net/Spaced-repetition" rel="noopener noreferrer"&gt;spaced repetition&lt;/a&gt;; 2 years ago I wasn't sure about this whole Anki thing, but I decided to give it a shot anyway, today I can say with confidence that it does work, but don't just take my word for it, I highly recommend that you read &lt;a href="https://apps.ankiweb.net/docs/manual.html#introduction" rel="noopener noreferrer"&gt;Anki's own introduction&lt;/a&gt;, and &lt;a href="https://www.gwern.net/Spaced-repetition" rel="noopener noreferrer"&gt;Gwern Branwen's excellent article about spaced repetition&lt;/a&gt; these two are more important than this post, read them if you have the time.&lt;br&gt;
I won't be exploring the program itself, it's relatively straight forward, and there are many &lt;a href="https://improveism.com/how-to-use-anki-tutorial/" rel="noopener noreferrer"&gt;great articles&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=bJFw9gBkvcY" rel="noopener noreferrer"&gt;videos&lt;/a&gt; out there that explain how to use it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Focjbpajwoq30zags4y1q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Focjbpajwoq30zags4y1q.jpg" alt="Johann Gutenberg, a painting by Granger"&gt;&lt;/a&gt;&lt;/p&gt;
Johann Gutenberg, by Granger



&lt;p&gt;When I'm reading a book, I highlight the parts that I think are important, and after I'm done reading, I start creating Anki cards for the highlighted parts, I try my best to write "good" cards for each highlighted part, this is the trickiest and the most important part, things that I avoid are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Questions related to language syntax.&lt;/li&gt;
&lt;li&gt;Questions that only require remembering what a specific method does.&lt;/li&gt;
&lt;li&gt;Questions like this one: “Lessons learned from chapter 2”.&lt;/li&gt;
&lt;li&gt;Creating cards with long answers; it's better to break them down to multiple smaller cards.&lt;/li&gt;
&lt;li&gt;Writing sketchy answers: only writing the keywords in the answer, or using sentences like "refer to page x" or "read article y"; this is bad because you not only want to answer the questions, but you also want to answer them the same way every time, and having to go through an article every time isn't exactly going to help you do that; it's also bad because you're assuming that you'll have access to the book or the article that you're referring to when doing your cards, which isn't always true, in my case for example, I tend to do my cards using my phone when commuting to work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I do is that I write questions that help me &lt;a href="https://en.wikipedia.org/wiki/Mental_model" rel="noopener noreferrer"&gt;develop my mental model&lt;/a&gt; for the topic I'm reading about, &lt;a href="https://rs.io/anki-tips/" rel="noopener noreferrer"&gt;these are usually "why?" questions&lt;/a&gt;,  I found this type of questions to be by far, the most effective; I also found that if there's an important part, and that part that has a diagram for it, then I can simply take a screenshot and use that diagram as the answer.&lt;/p&gt;

&lt;p&gt;Sometimes I find that there's an important part that I just can't convert to a flashcard format, in that case, I use &lt;a href="https://apps.ankiweb.net/docs/manual.html#note-types" rel="noopener noreferrer"&gt;“cloze cards”&lt;/a&gt;, they're simply fill-in-the-blank questions; I use this type sparingly as I always try to create regular cards instead.&lt;/p&gt;

&lt;p&gt;When you first start using Anki, you'll notice that you're spending relatively long periods of time to create new cards, this is perfectly normal, it actually indicates that you're putting effort into writing useful cards, don't worry thought, it gets easier by time.&lt;/p&gt;

&lt;p&gt;Everything I mentioned earlier applies to video content as well, the only difference is that instead of highlighting important parts, I type them, and sometimes I mark the important timestamps and go back to them after I'm done; I tend to use screenshots more often when creating cards for this type of content.&lt;/p&gt;

&lt;p&gt;There is one last type of cards that I use, I call them "implementation cards", I don't have many of them, and they're all combined in the same deck; I use them for questions that require actual code as an answer, for example I have a card for implementing &lt;a href="https://www.geeksforgeeks.org/quick-sort/" rel="noopener noreferrer"&gt;quick sort&lt;/a&gt;, and one that requires me &lt;a href="https://hackernoon.com/async-await-generators-promises-51f1a6ceede2" rel="noopener noreferrer"&gt;to convert a JavaScript async function to use promises and a generator function instead&lt;/a&gt;; again, I use this type sparingly, because answering this type is time consuming.&lt;/p&gt;

&lt;p&gt;There are many discussions regarding the "perfect" Anki deck configuration, for me, I use the default configuration with two minor changes, I increased the maximum number of new cards to 50 per day, and reduced the maximum review interval to 365 days. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5yv52hyflrowywn3qajs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5yv52hyflrowywn3qajs.jpg" alt="A Philosopher, a painting by Salvator Rosa"&gt;&lt;/a&gt;&lt;/p&gt;
A Philosopher, by Salvator Rosa



&lt;h1&gt;
  
  
  FAQ:
&lt;/h1&gt;

&lt;h2&gt;
  
  
  “But why memorize all of this? Just learn what you need as you go”
&lt;/h2&gt;

&lt;p&gt;I learn a lot by simply googling problems that I face when doing my daily tasks, however, in my opinion, there are a few problems with this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When learning something on the job, you’re usually trying to get something done, you don’t have the time to gain deep understanding of the problem or the solution; you probably won’t be able to see the bigger picture, or notice how the problem you're facing could be an indicator of a &lt;a href="https://refactoring.guru/refactoring/smells" rel="noopener noreferrer"&gt;more critical problem&lt;/a&gt;; there is a good chance that you’re learning a single solution for a single problem, which isn’t necessarily bad, but you can certainly do better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leaning only what you need means that if you don’t face a certain problem, then there’s a good chance that you will learn little to nothing about it; if you’re a front-end developer, you're not going to face back-end related problems, does that mean that you should ignore everything back-end related? If you’re working with relational databases, does that mean that you shouldn’t read about noSQL databases? If you’re a fullstack JavaScript developer, does that mean that you shouldn’t explore other languages? Many people might argue that you shouldn’t, but I think &lt;a href="https://medium.com/@jchyip/why-t-shaped-people-e8706198e437" rel="noopener noreferrer"&gt;you&lt;/a&gt; &lt;a href="https://codewithoutrules.com/2019/03/29/learn-new-technologies/" rel="noopener noreferrer"&gt;should&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learning  just enough is a &lt;a href="https://chelseatroy.com/2019/04/18/transcript-from-keynote-leveling-up/" rel="noopener noreferrer"&gt;passive way to level up, you should consider leveling up deliberately&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, if you have cards that cover fundamental concepts in your decks, then you should find technical interviews easier to do; you’re regularly reviewing your cards, so you won’t have to think about the phrasing of your answer during an interview; this also applies to implementation cards, they make preparing for white board interviews easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Why not invest more time in learning by doing instead of doing all of this Anki stuff?”
&lt;/h2&gt;

&lt;p&gt;learning by doing is great, however, there are a few things that you need to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when learning by doing, you might find that you're &lt;a href="https://refactoring.guru/design-patterns/why-learn-patterns" rel="noopener noreferrer"&gt;re-discovering patterns&lt;/a&gt;,what I mean by that is you might find yourself trying to describe a &lt;a href="https://refactoring.guru/design-patterns" rel="noopener noreferrer"&gt;problem or a solution that already has a name&lt;/a&gt;, knowing the term that describes a specific problem or a solution makes communicating it more efficient; for example, in React, I didn’t know that passing the same prop multiple levels down is called &lt;a href="https://kentcdodds.com/blog/prop-drilling/" rel="noopener noreferrer"&gt;“props drilling”&lt;/a&gt;; try googling your own description for props drilling, then google “props drilling”, notice how the results are better in the latter search.&lt;/li&gt;
&lt;li&gt;always try to find similarities between technologies, even if they were completely different; for example, each operation in &lt;a href="https://docs.mongodb.com/manual/core/replica-set-oplog/" rel="noopener noreferrer"&gt;MongoDB's oplog&lt;/a&gt; is idempotent. That is, oplog operations produce the same results whenever applied  to the target dataset, this is somewhat similar to how &lt;a href="https://redux.js.org/introduction/three-principles/" rel="noopener noreferrer"&gt;Redux works&lt;/a&gt;, if you call the same series of actions, you'll get the same resulting state, both of these behaviors are somewhat similar to the &lt;a href="https://martinfowler.com/eaaDev/EventSourcing.html" rel="noopener noreferrer"&gt;event sourcing pattern&lt;/a&gt;, they're not textbook implementations of it, but if you already understand one of them, you can use the same mental model to understand the other, and then you start to refine that mental model to accurately represent the new concept you're learning; what you're doing is that, instead of reasoning about a new concept as if it's completely new, you start to think of it as something close to a concept that you already understand well; it's important to note that you're not necessarily looking for "real" patterns, you're just looking for similarities that could help your understanding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  “What if I'm too busy to do my cards?”
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apps.ankiweb.net/docs/manual.html#frequently-asked-questions" rel="noopener noreferrer"&gt;consistency Is key here&lt;/a&gt;; even if you can’t do all the cards, then at least do some of them, the good thing is that even if you fail to answer some cards, you will simply see them more often, and you'll eventually have the answer memorized again.&lt;br&gt;
Don’t feel bad if you have many late cards, the last thing you want is yet another thing that makes you feel bad about yourself; the fact that you’re reading this blog post is a proof that you’re genuinely trying to learn something, so don’t be too hard on yourself.&lt;/p&gt;

</description>
      <category>learning</category>
    </item>
    <item>
      <title>Lessons learned in modern UI testing</title>
      <dc:creator>Ahmed Al-Obaidi</dc:creator>
      <pubDate>Fri, 10 Jan 2020 21:19:11 +0000</pubDate>
      <link>https://forem.com/muubar/lessons-learned-in-modern-ui-testing-5c1k</link>
      <guid>https://forem.com/muubar/lessons-learned-in-modern-ui-testing-5c1k</guid>
      <description>&lt;p&gt;I've been developing modern React-based UIs for a few months now, while also maintaining not-so-modern ones, and I recently faced a problem: I've tested web services before, but on the front-end, &lt;b&gt;I don't even know what to test&lt;/b&gt;; the problem wasn't that I couldn't find a tool to test with, there are &lt;a href="https://airbnb.io/enzyme/"&gt;many&lt;/a&gt; &lt;a href="https://github.com/Raathigesh/majestic"&gt;interesting&lt;/a&gt;  &lt;a href="https://testing-library.com/docs/react-testing-library/intro"&gt;testing&lt;/a&gt; &lt;a href="https://mochajs.org/"&gt;libraries&lt;/a&gt; out there, the problem was that I didn't even know how to approach testing UIs to begin with; our front-end tech lead is nice enough to let us try things around, so I did, and it was .. well .. frustrating, I noticed that most of the tests that i was writing were either breaking easily or were downright useless, so I read articles here and there, and did &lt;a href="https://kentcdodds.com/"&gt;Kent C. Dodds&lt;/a&gt; testing courses titled “JavaScript testing practices and principles” and “Testing React applications” that are available on &lt;a href="https://frontendmasters.com/"&gt;Frontendmasters&lt;/a&gt;; below is a summary of what I think are the most important points that were mentioned: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tests should not force you, or even encourage you, to rewrite parts of your implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Code_coverage"&gt;Code coverage&lt;/a&gt; is almost always a bad metric for how confident you are in the code you’re shipping; it’s also incorrectly used as a metric for code quality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code coverage tools implicitly assume that all blocks, statements, and lines of code are equal, but in reality, some are a lot more critical than others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The last 10% of code coverage is usually covered by tests that are hard to maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests should explicitly communicate the relationships between the expected result and other &lt;a href="https://stackoverflow.com/a/34459490"&gt;entities&lt;/a&gt; that are directly causing this result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests that resemble how the entity is actually used give more confidence in that entity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always be explicit about your &lt;a href="https://stackoverflow.com/a/2666006"&gt;mocks&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When mocking, you must ensure that the mocked entity and the entity that you’re testing are actually connected as expected, for example if you're calling an API and you mock this call, then you must first ensure that the entity you’re testing is actually able to send requests to that endpoint, you don’t have to write a test to check this kind of connection, a manual check is enough.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the formal definition of a &lt;a href="https://martinfowler.com/bliki/UnitTest.html"&gt;unit test&lt;/a&gt; you mock every single external dependency, otherwise you're writing an &lt;a href="https://martinfowler.com/bliki/IntegrationTest.html"&gt;integration test&lt;/a&gt;; when you mock everything you're focusing on this very specific entity that you're testing, it's fine to have shallow mocks as long as they behave as your entity expects them to behave.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clean up your testing DB before each test instead of after, this ensures that if a test fails, your DB would be in a debug-able state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;testing the CSS, or the overall styling of an entity is usually best done using &lt;a href="https://www.abhishek-tiwari.com/visual-regression/"&gt;visual regression tools&lt;/a&gt;, but if you're doing &lt;a href="//cssinjs.org"&gt;CSS-in-JS&lt;/a&gt; then you can do &lt;a href="https://jestjs.io/docs/en/snapshot-testing"&gt;snapshot testing&lt;/a&gt; that includes your CSS; this is considered a middle ground between regular tests and visual regression tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the problem with &lt;a href="https://airbnb.io/enzyme/"&gt;Enzyme&lt;/a&gt; is that it encourages testing implementation details, it causes extreme cases of &lt;a href="https://en.wikipedia.org/wiki/White-box_testing"&gt;white-box testing&lt;/a&gt;, for example: &lt;a href="https://reactjs.org/docs/shallow-renderer.html"&gt;shallow rendering&lt;/a&gt; implicitly mocks all inner components even if they live within the same module/file, another example would be the &lt;a href="https://airbnb.io/enzyme/docs/api/ReactWrapper/instance.html"&gt;“instance()”&lt;/a&gt; method, which gives you access to a component's class instance so that you can call methods directly, which encourages breaking the connection between the actual component and it’s methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshots can include the props of your components; however, including them is considering an implementation detail, because users don’t care about props.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good tests are the ones that would guide you through a refactoring process, tests that just fail when you do any kind of refactoring are not useful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do your best not to test state changes, users don’t care about how your internal state is changing, testing how these changes affect your UI is a lot more useful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshots can be easily abused; if someone runs a snapshot test, and it fails, and they don't carefully read the log before updating the snapshot, then this test is not even a test anymore; Snapshots heavily depend on the commitment of the team to be intentional about maintaining their tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshots tend to have a higher signal-to-noise ratio, it's difficult for someone to tell which parts are important, and which aren't, that’s why we should keep our snapshots small.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Snapshots are useful not just for DOM and DOM-like assertions, but also for object equality assertions, and specific error throwing assertion; they are easier to maintain compared to manually writing down the equality check, which is the more common approach for those types of assertions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a component’s smoke test fails because it expects a &lt;a href="https://reactjs.org/docs/context.html"&gt;provider&lt;/a&gt; ( Redux store, browserRouter, etc..) then you should simply render it with that provider.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s perfectly fine to first setup the test by doing manipulations that depend on implementation details in order to reflect a specific scenario that your test depends on, just make sure that the actual core of your test is not following the same approach.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm interested to see how things will go from here.&lt;br&gt;
At the end I'd like to share &lt;a href="https://martinfowler.com/testing/"&gt;this treasure&lt;/a&gt; with you.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>ui</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
