<?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>DEV Community: Talina</title>
    <description>The latest articles on DEV Community by Talina (@talina).</description>
    <link>https://dev.to/talina</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%2F789102%2F7e773036-f0a0-4a87-a773-26da8ab5e3ce.jpg</url>
      <title>DEV Community: Talina</title>
      <link>https://dev.to/talina</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/talina"/>
    <language>en</language>
    <item>
      <title>3 Integration Testing Tips For Developers To Release Software With Confidence</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Thu, 20 Jan 2022 04:40:49 +0000</pubDate>
      <link>https://dev.to/talina/3-integration-testing-tips-for-developers-to-release-software-with-confidence-2gca</link>
      <guid>https://dev.to/talina/3-integration-testing-tips-for-developers-to-release-software-with-confidence-2gca</guid>
      <description>&lt;p&gt;Earlier, we discussed &lt;a href="https://dev.to/talina/thumb-rules-of-unit-testing-45of"&gt;the thumb rules of unit testing.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unit tests form the first level in the &lt;a href="https://martinfowler.com/articles/practical-test-pyramid.html"&gt;Test Pyramid&lt;/a&gt; - we achieve faster results by assuming behaviour for all external boundaries.&lt;/p&gt;

&lt;p&gt;Integration tests are a step ahead - they sufficiently test the communication over these external boundaries.&lt;/p&gt;

&lt;p&gt;Here are 3 things developers should keep in mind while writing integration tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  #1 Deconstruct The External Interactions
&lt;/h2&gt;

&lt;p&gt;Allow integration tests to be &lt;a href="https://martinfowler.com/bliki/IntegrationTest.html"&gt;&lt;em&gt;narrow&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Integration tests validate if two separately developed units work well together.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can allow integration testing to be white-box if we test each integration point at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: An application interacts with a database and an external API service.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Integration testing for database interaction - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Start a database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Invoke the code that performs database operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate the operations were successful.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The integration test can mock all other external interactions as it only tests database interactions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Narrow integration tests test for one integration point at a time.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  #2 Use Local Environment
&lt;/h2&gt;

&lt;p&gt;We don't need to initiate an entire stack to run integration tests if they are narrow.&lt;/p&gt;

&lt;p&gt;All external services should be set up locally so that integration tests can be run during the development phase and reduce any operational hassles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A local setup makes integration tests fast and easy to run -  they can be added to the build pipeline with ease.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example: A single deployment file that spins up services on your laptop using an orchestrator such as "docker".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A local setup makes integration tests more deterministic - we remove network failures.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  #3 Test Doubles Are Acceptable
&lt;/h2&gt;

&lt;p&gt;External services don't always imitate exact behaviour in a local environment.&lt;/p&gt;

&lt;p&gt;The local instance could be unofficial or mismatch the latest versioned behaviour.&lt;/p&gt;

&lt;p&gt;In such a case, we should opt for mocking the service at the last level of interaction by using appropriate test doubles.&lt;/p&gt;

&lt;p&gt;These test doubles guarantee that the &lt;a href="https://martinfowler.com/ieeeSoftware/published.pdf"&gt;public interfaces&lt;/a&gt; work as expected.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Narrow integration tests validate clients not servers.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>codequality</category>
      <category>devrel</category>
    </item>
    <item>
      <title>Top 3 Ways to Log Errors to Simplify Debugging For Systems Engineers</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Sat, 15 Jan 2022 15:22:21 +0000</pubDate>
      <link>https://dev.to/talina/top-3-ways-to-log-errors-to-simplify-debugging-for-systems-engineers-2lh9</link>
      <guid>https://dev.to/talina/top-3-ways-to-log-errors-to-simplify-debugging-for-systems-engineers-2lh9</guid>
      <description>&lt;p&gt;How often do you find yourself spending hours trying to triage a failure in production?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Debugging is challenging because &lt;em&gt;&lt;strong&gt;we don't know what we're looking for&lt;/strong&gt;&lt;/em&gt;, and to top it off, &lt;em&gt;&lt;strong&gt;we have no way to pick on the trail of errors&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most obvious first step is to ensure all services are logging errors to a standard logging tool.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Logs are your guardian angels when it comes to finding root causes of failures.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's understand how to befriend these angels and streamline debugging.&lt;/p&gt;

&lt;p&gt;Here's a sample scenario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;A user wants to open an online bank account.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backend function calls are -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. (api) POST /accounts
    2. (api) CreateAccountHandler()
       2.1 (internal) AccountsSvc.InitiateCreateAccount()
       2.2 (internal) AccountsSvc.ValidateUser()
           2.2.1 (validator) ValidateID()
       2.3 (internal) AccountsSvc.ValidateBankDetails()
           2.3.1 (validator) ValidateID()
       2.4 (internal) AccountsSvc.CreateAccount()
           2.4.1 (database) Store.SaveAccountDetails()
                 2.4.1.1 (writer) Data.Write()
     3. (serialization) Response.Serialize()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  #1 Relative Messaging
&lt;/h2&gt;

&lt;p&gt;Steps 2.2.1 and 2.3.1 have the same ValidateID() function call.&lt;br&gt;
If the &lt;strong&gt;ValidateID()&lt;/strong&gt; call fails to validate the user, we want to log about this correlation to pinpoint the exact failure.&lt;br&gt;
Use this template across &lt;em&gt;all appropriate&lt;/em&gt; levels -&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Failed to perform X while attempting to do Y&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, a failure in ValidateID() at 2.2.1 would result in errors logged from the bottommost to the topmost caller -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error Log Trace
- (validator/ValidateID) Failed to validate the ID.
- (internal/ValidateUser) Failed to validate the ID while attempting to validate user details.
- (internal/InitiateCreateAccount) Failed to validate user details while attempting to create a new account.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  #2 Log Across Microservices
&lt;/h2&gt;

&lt;p&gt;Imagine there are 2 microservices involved in this sample example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API service accepts incoming http requests.
Internal Service performs the CreateAccount operations.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all microservice log the shared context, correlating the API service errors with internal service becomes easy.&lt;/p&gt;

&lt;p&gt;The shared context is metadata that helps filter loglines - a request ID, a user ID or an account ID.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A logline is the "vertex", and the shared context is the segment that connects each vertex.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  #3 Avoid Pseudo Errors
&lt;/h2&gt;

&lt;p&gt;We retry operations to deal with intermittent failures such as a flaky network.&lt;br&gt;
Use the correct log level to separate intermittent failures from final failures.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A simple way to do this is by using the "warn" level for intermittent failures and the "error" level for the final failure.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I hope these simple improvements streamline debugging failures.&lt;/p&gt;

&lt;p&gt;Want to add more best practices to this list? Let me know in the comments!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>codequality</category>
      <category>operations</category>
      <category>devops</category>
    </item>
    <item>
      <title>Let's Chat About Contexts in Go</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Thu, 13 Jan 2022 17:45:33 +0000</pubDate>
      <link>https://dev.to/talina/lets-chat-about-contexts-in-go-152e</link>
      <guid>https://dev.to/talina/lets-chat-about-contexts-in-go-152e</guid>
      <description>&lt;p&gt;Today I want to have a brief chat about Contexts in Go. :)&lt;/p&gt;

&lt;p&gt;Every Go developer uses Contexts in their coding lifetime.&lt;/p&gt;

&lt;p&gt;Read this &lt;a href="https://go.dev/blog/context"&gt;profound yet straightforward blog&lt;/a&gt; if you are new to Go and Contexts.&lt;/p&gt;

&lt;p&gt;To excel as a developer, we should actively make an effort to understand the &lt;strong&gt;"why"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are many great articles on the web about using Contexts in Go and the how-to.&lt;/p&gt;

&lt;p&gt;But, let's mull over &lt;strong&gt;&lt;em&gt;why&lt;/em&gt;&lt;/strong&gt; should Contexts be used in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  Carriers of Metadata
&lt;/h2&gt;

&lt;p&gt;Contexts &lt;a href="https://pkg.go.dev/context#example-WithValue"&gt;carry miscellaneous metadata&lt;/a&gt; that is helpful for each invoked function call. This metadata could include the caller's information or general identification information. &lt;/p&gt;

&lt;p&gt;This metadata is also helpful while debugging incoming requests if we log the messages with the context information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources Saver!
&lt;/h2&gt;

&lt;p&gt;Contexts offer &lt;a href="https://pkg.go.dev/context#CancelFunc"&gt;an ability to cancel an ongoing operation&lt;/a&gt; if - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The caller invoked a cancellation -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imagine a scene where a flick to the first domino makes all subsequent dominos fall.&lt;/li&gt;
&lt;li&gt;That is how the parent Context's &lt;a href="https://pkg.go.dev/context#CancelFunc"&gt;CancelFunc&lt;/a&gt; cancels derived contexts.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;When the operation takes longer than expected -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In this case, the Context's cancel logic is invoked when the &lt;a href="https://pkg.go.dev/context#WithDeadline"&gt;configured deadline&lt;/a&gt; exceeds, and this cancellation propagates to the derived contexts.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The advantage of context cancellation is that all goroutines exit immediately, and the application can reclaim used resources such as memory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Using Contexts is a way to safeguard resource consumption.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;If you want to understand Contexts in-depth, I recommend you head over to these links - &lt;/p&gt;

&lt;p&gt;&lt;a href="https://go.dev/blog/context-and-structs"&gt;Contexts and Structs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This blog advocates a noteworthy takeaway - &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Context makes it easy to propagate important cross-library and cross-API information down a calling stack. But, it must be used consistently and clearly in order to remain comprehensible, easy to debug, and effective.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://pkg.go.dev/context"&gt;Context Pkg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the How-To.&lt;/p&gt;

&lt;p&gt;Until Later!&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>ADRs Done Right</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Wed, 12 Jan 2022 18:22:45 +0000</pubDate>
      <link>https://dev.to/talina/adrs-done-right-4271</link>
      <guid>https://dev.to/talina/adrs-done-right-4271</guid>
      <description>&lt;p&gt;As a Software Engineer, I have had the opportunity to write multiple &lt;a href="https://en.wikipedia.org/wiki/Architectural_decision"&gt;Architecture Decision Records(ADRs)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Head over to &lt;a href="https://engineering.atspotify.com/2020/04/14/when-should-i-write-an-architecture-decision-record/"&gt;Spotify's Blog Post&lt;/a&gt; for in-depth reading.&lt;/p&gt;

&lt;p&gt;An ADR answers two questions -&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the problem?&lt;br&gt;
How should we solve it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writing ADRs brings clarity and binds teams to a &lt;em&gt;common goal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;ADRs serve as suitable &lt;em&gt;communication mediums&lt;/em&gt; for new team members - they can live the past without being there.&lt;/p&gt;

&lt;p&gt;Let's dive deeper into the art of writing an ADR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Depth of Solution
&lt;/h2&gt;

&lt;p&gt;ADRs should solve the problem, but the way it's solved shouldn't matter if the constraints are apparent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ex: Rotate credentials every 24 hours.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The implementation doesn't matter - it could be a cron, manual or a scheduler service; the details lie with the folks who work on it.&lt;/p&gt;

&lt;p&gt;What is necessary is that the credentials should have a shelf-life of 24 hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Your Assumptions
&lt;/h2&gt;

&lt;p&gt;State assumptions to gauge if the design becomes obsolete.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ex: How much data traffic rate can the software support?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Provided the technique is reliable and resilient, we should -&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Architect for the future, but settle for simplicity.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Security Aspects
&lt;/h2&gt;

&lt;p&gt;Security is vital for software dealing with sensitive customer information, including accessing customer data.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://en.wikipedia.org/wiki/STRIDE_%28security%29"&gt;"Threat Modeling"&lt;/a&gt; exercise done in advance to cover all security breaches goes a long way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Costing Aspects
&lt;/h2&gt;

&lt;p&gt;Every offering of your software product has a fixed, affordable budget, and a technical decision is almost always strongly linked with this cost.&lt;/p&gt;

&lt;p&gt;Does the design involve a managed service? It's good to include baseline costing for data transfer, hourly rates and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Decision Record
&lt;/h2&gt;

&lt;p&gt;Before writing the ADR, an array of discussions happen in the background.&lt;/p&gt;

&lt;p&gt;Every ADR should have a &lt;strong&gt;"decision"&lt;/strong&gt; section which states a single locked-in decision - assimilation of all the discussion meetings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In conclusion, when it comes to writing ADRs -&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The key is to promote &lt;em&gt;transparency and participation&lt;/em&gt; while maintaining &lt;em&gt;focus and ownership&lt;/em&gt; of the architecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's all for today! Until later!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>architecture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Thumb Rules of Unit Testing</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Tue, 11 Jan 2022 16:45:07 +0000</pubDate>
      <link>https://dev.to/talina/thumb-rules-of-unit-testing-45of</link>
      <guid>https://dev.to/talina/thumb-rules-of-unit-testing-45of</guid>
      <description>&lt;p&gt;My ideas on writing meaningful unit tests were crystallized when I read &lt;a href="https://martinfowler.com/articles/practical-test-pyramid.html#UnitTests"&gt;"The Practical Test Pyramid"&lt;/a&gt; today.&lt;/p&gt;

&lt;p&gt;As a novice programmer, I went in mindlessly, not knowing how to test my code.&lt;/p&gt;

&lt;p&gt;The Practical Test Pyramid is an excellent guide, but I want to emphasize unit testing today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Write Unit Tests?
&lt;/h2&gt;

&lt;p&gt;As the name suggests - you test a &lt;strong&gt;"unit"&lt;/strong&gt; of your code.&lt;/p&gt;

&lt;p&gt;Unit tests are beneficial in ensuring the code works as intended - it is the first step towards being confident about the logic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Unit tests have the narrowest scope of all the tests in your test suite.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A service accesses a database to perform &lt;strong&gt;a set of computations&lt;/strong&gt;; the unit tests will cover all edge cases for the performed computations. The access to the database is &lt;strong&gt;"assumed"&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Write Good Unit Tests?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cover Non-Trivial Cases
&lt;/h3&gt;

&lt;p&gt;Test for all edge cases in the code.&lt;/p&gt;

&lt;p&gt;Typically, you won't test if input deserialization works unless you've written the library itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;When it comes to unit testing, aim for &lt;strong&gt;confidence coverage&lt;/strong&gt; and not code coverage.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Test for Observable Behavior
&lt;/h3&gt;

&lt;p&gt;Loosely couple tests and code. Refactoring code is a common practice, but refactoring unit tests is stressful.&lt;/p&gt;

&lt;p&gt;Unit tests should always answer two questions -&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the input?&lt;br&gt;
&lt;em&gt;Is the output expected?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Structure
&lt;/h3&gt;

&lt;p&gt;Tests, like your code, should be easy to read and understand.&lt;/p&gt;

&lt;p&gt;Most supporters of TDD derive code from tests. Hence, a readable structure goes a long way in translating behaviour into code.&lt;/p&gt;

&lt;p&gt;Use &lt;a href="https://martinfowler.com/bliki/GivenWhenThen.html"&gt;"Given, When, Then"&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Given an input X&lt;/li&gt;
&lt;li&gt;When function Y executes&lt;/li&gt;
&lt;li&gt;Then the outcome is Z&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ensure you maintain a delicate balance between &lt;strong&gt;DRY(Don't Repeat Yourself)&lt;/strong&gt; and &lt;strong&gt;DAMP(Descriptive and Meaningful Phrases)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/6453235/what-does-damp-not-dry-mean-when-talking-about-unit-tests"&gt;Read more about why repetition is acceptable in tests.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TestDoubles
&lt;/h3&gt;

&lt;p&gt;We can use various &lt;a href="https://martinfowler.com/bliki/TestDouble.html"&gt;TestDoubles&lt;/a&gt; to replace production objects for testing purposes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;em&gt;stubs&lt;/em&gt; in cases where branching logic doesn't matter. 
We don't care if the database write fails.&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;mocks&lt;/em&gt; when the order and the output matter. 
We care if the database write fails the second time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More at &lt;a href="https://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks aren't Stubs.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know how you write unit tests in the comments!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>codequality</category>
      <category>programming</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>5 Big Mistakes Companies Make When Testing Software</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Tue, 11 Jan 2022 04:40:28 +0000</pubDate>
      <link>https://dev.to/talina/5-big-mistakes-companies-make-when-testing-software-2604</link>
      <guid>https://dev.to/talina/5-big-mistakes-companies-make-when-testing-software-2604</guid>
      <description>&lt;p&gt;Most software companies struggle with releasing quality code that doesn't break critical user workflows.&lt;/p&gt;

&lt;p&gt;Companies invest significant dollars in testing their product to counter this but often ship a P0 bug anyway.&lt;/p&gt;

&lt;p&gt;Here are 5 root causes for software bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  #1 Inconsistent Testing Environments
&lt;/h3&gt;

&lt;p&gt;A common mistake and often a harder one to fix during the nascent phases of software.&lt;/p&gt;

&lt;p&gt;Naturally, if the pre-production environment never hits an edge case that can occur in production, it is impossible to validate enhancements accurately.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Thought:&lt;/strong&gt; &lt;em&gt;Deploy a snapshot of the production environment as a pre-release environment.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  #2 Backwards Incompatibility
&lt;/h3&gt;

&lt;p&gt;Engineering teams write code to work in the "present" and the "future", making version testing hard. Software should not be forward-facing.&lt;/p&gt;

&lt;p&gt;Example: Release #1 deploys software with a v1 dependency, and release #2 now uses a v2 version of the dependency. This change is non-idempotent - we wipe out a variable value by storing only the latest state. &lt;/p&gt;

&lt;p&gt;What happens to the deployed state that works with a v1 dependency? Does it break or work with the new release?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Thought:&lt;/strong&gt; &lt;em&gt;Always support X states of existing data. Streamline rollbacks.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  #3 Treating Infrastructure and Microservices Separately
&lt;/h3&gt;

&lt;p&gt;As more folks campaign for infrastructure as code, we move towards automating infrastructure deployments.&lt;/p&gt;

&lt;p&gt;But does a change in automation break existing infrastructure?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Thought:&lt;/strong&gt; &lt;em&gt;Can backward compatibility testing solve this problem?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  #4 Ignoring the Network
&lt;/h3&gt;

&lt;p&gt;Assuming the network behaves the same irrespective of time and region is a recipe for software failure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Thought:&lt;/strong&gt; &lt;em&gt;Can Edge Testing gauge pre-release software inconsistencies?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  #5 Testing Features in Silos
&lt;/h3&gt;

&lt;p&gt;With the microservices architecture, a change in one service can cause a failure in unrelated user functionality. Testing a new release in a silo for a fixed subset of features doesn't help.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Thought:&lt;/strong&gt; &lt;em&gt;Replay tests for all critical user workflows for every release to generate an accurate failures heatmap.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me know if you've solved any of these mistakes and how.&lt;/p&gt;

&lt;p&gt;Until later! :)&lt;/p&gt;

</description>
      <category>testing</category>
      <category>performance</category>
      <category>codequality</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Kickstart Your Journey as a Go Engineer in 4 Easy Steps</title>
      <dc:creator>Talina</dc:creator>
      <pubDate>Sun, 09 Jan 2022 18:35:33 +0000</pubDate>
      <link>https://dev.to/talina/kickstart-your-journey-as-a-go-engineer-in-4-easy-steps-mhk</link>
      <guid>https://dev.to/talina/kickstart-your-journey-as-a-go-engineer-in-4-easy-steps-mhk</guid>
      <description>&lt;p&gt;A structured approach to learning goes a long way in maximizing your output as a developer. Why struggle with theory when you can code immediately?&lt;/p&gt;

&lt;p&gt;As an entrant, look for small wins every day - the key is to get instant gratification by writing production-grade Go.&lt;/p&gt;

&lt;h2&gt;
  
  
  #1 Win at the Syntax Game
&lt;/h2&gt;

&lt;p&gt;A developer communicates through code; the first obvious step is to learn the syntax - a language's grammar.&lt;/p&gt;

&lt;p&gt;Learning syntax can be slow - one has to remember many minute details. But thanks to &lt;a href="https://gobyexample.com/"&gt;gobyexample&lt;/a&gt;, this has been made simple.&lt;/p&gt;

&lt;p&gt;Run the code snippets in &lt;a href="https://play.golang.org/"&gt;Go's Playground&lt;/a&gt;. Tweak the code and implement various use-cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Another excellent news:&lt;/strong&gt; Go offers limited in-built data structures, so the learning curve is shallow.&lt;/p&gt;

&lt;h2&gt;
  
  
  #2 Read Code to Write Code
&lt;/h2&gt;

&lt;p&gt;Read code to incorporate different design patterns.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Read code with an eye for design but a vision to improve it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Review code - read other reviewers' comments, ask questions, seek clarity. This is a proven method to grasp the language better.&lt;/p&gt;

&lt;h2&gt;
  
  
  #3 Master Best Practices
&lt;/h2&gt;

&lt;p&gt;Want to master a coding language? Learn its best practices.&lt;/p&gt;

&lt;p&gt;One language's guidelines don't apply to another. Even as a proficient &lt;a href="https://go.dev/blog/gopher"&gt;Gopher&lt;/a&gt;, you'll find yourself revisiting &lt;a href="https://go.dev/doc/effective_go"&gt;Effective Go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Conquering best practices goes a long way in writing maintainable code that can be tested quickly and refactored fewer times.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Communicating with your code will be easier if your code has a structure that most engineers know.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  #4 Make Your First Contribution!
&lt;/h2&gt;

&lt;p&gt;Make your first contribution while learning the syntax.&lt;/p&gt;

&lt;p&gt;Create an HTTP service. Next, are you able to write a CLI service in Go?&lt;/p&gt;

&lt;p&gt;Shadow other developers. Pick a low-hanging fruit - fixing a bug in a codebase, enhancing an API or writing a new script. Find a proficient colleague who can review your work.&lt;/p&gt;

&lt;p&gt;There are tons of &lt;a href="https://github.com/topics/go"&gt;open-source projects in Go&lt;/a&gt;; contribute to these fantastic projects.&lt;/p&gt;

&lt;p&gt;I hope you master Go by following these quick tips.&lt;br&gt;
May the force be with you!&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>career</category>
    </item>
  </channel>
</rss>
