<?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: tom-hartz</title>
    <description>The latest articles on DEV Community by tom-hartz (@tomhartz).</description>
    <link>https://dev.to/tomhartz</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%2F370604%2F635c8a3b-3d0f-4973-b86f-3920ee4eba3d.jpeg</url>
      <title>DEV Community: tom-hartz</title>
      <link>https://dev.to/tomhartz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tomhartz"/>
    <language>en</language>
    <item>
      <title>Using Firebase for Push Notifications</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:23:36 +0000</pubDate>
      <link>https://dev.to/leading-edje/using-firebase-for-push-notifications-2lnl</link>
      <guid>https://dev.to/leading-edje/using-firebase-for-push-notifications-2lnl</guid>
      <description>&lt;p&gt;&lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;Firebase&lt;/a&gt; is a mobile app development toolkit published by Google that can perform many different functions. In this article, we will look at how to implement Push Notifications using Firebase Cloud Messaging (FCM). &lt;/p&gt;

&lt;h2&gt;
  
  
  Account creation and Project settings
&lt;/h2&gt;

&lt;p&gt;To get started, you will first create an account and configure your application using &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;Firebase console&lt;/a&gt;. After creating the project, open Project settings (gear icon) and then follow the steps for adding iOS and Android apps to the project. During this setup you will download config files for both platforms: [GoogleService-Info.plist] for iOS and [google-services.json] for Android. The config files are used by firebase at runtime to link your app to your firebase account. You will need to bundle these config files and add the Firebase SDK to each app. &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%2Fx9ifui1cold1fcldsuxz.png" 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%2Fx9ifui1cold1fcldsuxz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For iOS, there is additional configuration required to enable push notifications. In the Firebase console Project settings, select "Cloud Messaging" and the "iOS app configuration" section should appear. Here you have two options for configuration: APNs Authentication Key and APNs Certificates. &lt;/p&gt;

&lt;p&gt;Using certificates is tricky. You first create the certs for both development and distribution from the Apple developer portal, then need to download and export them as .p12 files from your Keychain Access app (Mac OS is required here). After getting them uploaded correctly, there are still headaches to this approach. Using the Firebase console to send test notifications uses the Development cert, however if you use the FCM API to send notifications from your own backend it will always use the Production cert for the notification (regardless of you having your own development backend environment). This means that the notification will only appear on your device if you have signed the app for Distribution, which is problematic for developing and testing internally. &lt;/p&gt;

&lt;p&gt;Instead of having to deal with these signing compatibility issues, the recommended approach is to use an APNs Authentication Key. You need to create just one key in the Apple developer portal, export it as a .p8 file from your keychain, and upload it to the Firebase console. This key is compatible with both Development and Distribution provisioning profiles which simplifies things considerably. &lt;/p&gt;

&lt;h2&gt;
  
  
  App code &amp;amp; Firebase Tokens
&lt;/h2&gt;

&lt;p&gt;In your app code you will need to make a call to initialize the Firebase SDK during startup. For native apps, there is code provided in the app creation step. For hybrid apps, there are plugins available that handle this for you (I have used and recommend &lt;a href="https://github.com/arnesson/cordova-plugin-firebase" rel="noopener noreferrer"&gt;this same plugin&lt;/a&gt; handles that for you as well). &lt;/p&gt;

&lt;p&gt;Firebase tokens, also sometimes referred to as Registration ID's, are special identifiers that uniquely identify a mobile device and will be used to send our notifications. Your app needs to use the sdk to call "getToken". You will need to provide logic to handle saving and uploading the token to your backend. You should also use the SDK to register a callback function with "onTokenRefresh". Be aware that Google may at some point expire an FCM token, and in that event the onTokenRefresh method will be invoked to inform your app of the newly generated token. Your app should handle replacing and updating that token through to your backend as well. &lt;/p&gt;

&lt;h2&gt;
  
  
  Notification Icons
&lt;/h2&gt;

&lt;p&gt;On iOS the notifications will appear on the device and display them with your app icon. For Android, push notification icons are different from the app icon and must be provided separately. The standard here is to use an alpha grey scale image, and apply a color to the icon using either hard coded in the AndroidManifest.xml file or dynamically in the notification payload. Something to keep in mind with Android icon color is that you do not have full freedom to use any color! Whatever color you set will be &lt;a href="https://stackoverflow.com/a/49833431/2360569" rel="noopener noreferrer"&gt;overridden by Android&lt;/a&gt; to ensure that it has a good contrast. In my example below, the color I specify in the FCM payload (#96c93e) is changed when displayed on my Android phone (#508400). &lt;/p&gt;

&lt;p&gt;Android Studio provides a tool for generating the different icon resolutions. Right click on your project folder and select New &amp;gt; Image Asset. Select "Notification Icons" for the Icon Type, then for Asset Type choose "Image" and choose a file for Path: &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%2F54frdaxnc3i4vqjnerhi.png" 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%2F54frdaxnc3i4vqjnerhi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You then can specify the dynamically sized icon to use in the AndroidManifest.xml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.google.firebase.messaging.default_notification_icon"&lt;/span&gt; &lt;span class="na"&gt;android:resource=&lt;/span&gt;&lt;span class="s"&gt;"@drawable/notification_icon"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sending Notifications
&lt;/h2&gt;

&lt;p&gt;There are generally two options for generating push notifications from your backend: SDK or rest call. The &lt;a href="https://firebase.google.com/docs/cloud-messaging/admin/send-messages" rel="noopener noreferrer"&gt;here&lt;/a&gt; will instruct you on how to send push notifications to individual devices. &lt;/p&gt;

&lt;p&gt;Alternatively, you may use the FCM &lt;a href="https://firebase.google.com/docs/cloud-messaging/migrate-v1" rel="noopener noreferrer"&gt;REST API&lt;/a&gt; ("raw protocols") to send notifications using a standard POST web request. There are currently two versions of the REST API. The legacy version is the only one that supports "multicast" messaging (send a notification to multiple devices with one POST). You must include your Firebase Server key (found in Firebase Console &amp;gt; Project settings &amp;gt; Cloud Messaging) in the auth header. An example request looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;POST: https://fcm.googleapis.com/fcm/send
 Headers:
 Content-Type: application/json
 Authorization: key=YOUR_FIREBASE_SERVER_KEY_HERE
 Body:
 { 
   "registration_ids": ["YOUR_FCM_TOKEN_HERE"],
   "content_avaliable": true,
   "priority": "high",
   "notification": {
       "title": "Notification Demo",
       "body": "Testing push notifications!",
       "color": "#96c93e"
   }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With everything configured correctly, you should be able to send push notifications from your server and see them appear on your device!&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%2F4m79hw6kyyfe99qp32pe.png" 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%2F4m79hw6kyyfe99qp32pe.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ios</category>
      <category>android</category>
      <category>firebase</category>
    </item>
    <item>
      <title>iOS Code Signing and Deployment, Explained</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:23:27 +0000</pubDate>
      <link>https://dev.to/leading-edje/ios-code-signing-and-deployment-explained-2hf2</link>
      <guid>https://dev.to/leading-edje/ios-code-signing-and-deployment-explained-2hf2</guid>
      <description>&lt;p&gt;For the uninitiated, deploying apps onto iOS devices can be a daunting and downright confusing process. When developing a mobile app, simulators are great for rapidly going through the code-test loop. However it is still a good idea to test your app on physical devices early and often. Eventually you will want to distribute versions of your app for both internal testing and for production releases as well. XCode has improved quite a bit over the years, making this a lot easier than it used to be. This article will attempt to make clear the requirements for deploying to iOS devices and describe the process of getting an app onto devices.&lt;/p&gt;

&lt;p&gt;To deploy applications on iOS, you will need a computer running OS X (MacBook). You will also need to enroll in the &lt;a href="https://developer.apple.com/programs/"&gt;Apple Developer Program&lt;/a&gt;, for which Apple charges $99 per year. You then will have to register devices manually in the apple iOS dev website, or automatically through XCode. Note that you are limited to registering 100 devices of each type, to which you can deploy directly via USB (100 iPhones, 100 iPads, 100 Apple Watches, etc). When you connect a device through USB, XCode can automatically create a "provisioning profile" for your app, which is essentially a digital signature that allows the app to run on a device. Development builds that are deployed in this manner expire after 90 days.&lt;/p&gt;

&lt;p&gt;Another way to deploy dev builds is with Apple's &lt;a href="https://developer.apple.com/testflight/"&gt;Test Flight&lt;/a&gt;. You can create a Test Flight configuration where you can build your app and upload the ipa file (app bundle) to Apple. Each version of your app can then be released to your team for testing. Here, the limits are 1000 users with 10 devices each. Test users will first need to register and install the Test Flight app, through which they can access and install the released app versions. Again, builds deployed this way will only be able to run on the device for 90 days.&lt;/p&gt;

&lt;p&gt;To deploy to the app store, you must build and sign your app for release, and upload it to Apple. You can then configure an app submission through &lt;a href="https://appstoreconnect.apple.com/"&gt;App Store Connect&lt;/a&gt; (formerly iTunes Connect). Once the team from Apple has reviewed and approved your submission, your app will appear in the app store and be available for download. Releases deployed this way will not expire.&lt;/p&gt;

&lt;p&gt;To deploy releases without the app store, you will need to enroll in the &lt;a href="https://developer.apple.com/programs/enterprise/"&gt;Apple Developer Enterprise Program&lt;/a&gt; which costs $299 per year. This is a separate account, in addition to the $99 Developer Program if you still want to deploy to App Store! The Enterprise program will allow you to create provisioning profiles that can be deployed to devices without the app store. These builds can be deployed by hosting the app with an internal website/download link, and via USB or third party tools like HockeyApp.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ios</category>
    </item>
    <item>
      <title>Security Practices for Mobile App Developers</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:23:16 +0000</pubDate>
      <link>https://dev.to/leading-edje/security-practices-for-mobile-app-developers-14n1</link>
      <guid>https://dev.to/leading-edje/security-practices-for-mobile-app-developers-14n1</guid>
      <description>&lt;p&gt;A lot of my time writing software is spent concerned about things other than security. From the companies and projects I've seen, security usually ends up being either completely forgotten, or prioritized behind all the other important things like functionality, UX, test coverage, and performance. Managers and other stakeholders usually are motivated to spend just enough time and money on a project so that it is functional in the form of a minimum viable product. Security is often not a concern for them, until it is too late!&lt;/p&gt;

&lt;p&gt;As developers then, it is our ethical responsibility to ensure we follow best practices and keep security in the forefront of our minds. As craftsmen we must strive for the applications and tools that we create to be robust and impenetrable to outside intruders. Architects should be thinking about this often, but ideally even junior level developers should be aware of the basic best practices and techniques. It seems prudent to talk about some of the security concerns around mobile application development.&lt;/p&gt;

&lt;p&gt;Perhaps most obvious is that you should secure all API communications with SSL encryption. It's generally best to just use HTTPS to transmit all data between devices and servers, but especially sensitive data. Sensitive data includes Personally Identifiable Information (PII), your user's password, user activity, company trade secrets, etc. There can be exceptions to this of course. If the data is not sensitive, or if the communication is only occurring on internal private networks, then maybe you don't need to encrypt it. But it's not hard to use SSL. Keep in mind, SSL alone does not make your application data 100% safe. Attackers have many other means to steal data, so packet encryption on the network is just the first step. Also, if you've heard of &lt;a href="https://en.wikipedia.org/wiki/Heartbleed"&gt;Heartbleed&lt;/a&gt;, you know that even widely used SSL implementations can sometimes be faulty. But flatly, its 2018 people, secure your friggin' endpoints!&lt;/p&gt;

&lt;p&gt;Sensitive data should be encrypted "in-motion" (on the network through SSL secured APIs) and "at rest" (when stored in a database on a server or on a phone). Local storage is a very common feature in mobile apps, and data should be encrypted here as well. The only time sensitive data should ever be unencrypted, is temporarily in RAM, and on a screen displayed to an authorized user. Encrypting local storage is a security practice that makes sure a compromised device does not make application data readily available to a thief.&lt;/p&gt;

&lt;p&gt;A handy way to store small bits of information securely in an app is with the device Keychain (iOS/Android). Keychain frameworks provided by Apple and Google essentially guard data so that it can only be accessed by the registered application at runtime. Now, there are older OS versions and jailbreaks out there where it possible to decrypt and read this application data, so you should always consider the tradeoffs and only store data on device when it is absolutely necessary. Is it really important that the user have access to this data offline? Can it be stored on the server and accessed via secure communication instead?&lt;/p&gt;

&lt;p&gt;If you need to store more than a handful of secrets, you probably are using a more performant local storage option such as SQLite. This can also be encrypted! One approach is to encrypt/decrypt individual data fields on their way into and out of the data access layer of your application. However this is a bit cumbersome and more processing intensive than simply encrypting the entire database file, which your app can then decrypt into memory just once when it starts (the SQLite file will still be encrypted in the file system). DO NOT hardcode the encryption key(s) into your source code! I wouldn't trust putting keys into a private repo either (Github has been hacked before). Ideally, each app instance should have a unique encryption key. You can store the encryption keys in the Keychain, or fetch them from an API. The latter implies that users would have to be online to do an initial login, then can go offline as long they don't fully quit the app. Encrypting data this way can make it frustrating or impossible for an attacker to access when a phone gets lost or stolen.&lt;/p&gt;

&lt;p&gt;When a device is known to have been lost or stolen, it is good to have a contingency plan. A remote wipe is possible from the OS, and also something that you can custom build into your app (push notifications can trigger background process to start). However you should also consider that the user might not be immediately aware that they lost their phone. For this reason you should make logins expire as reasonably quickly as possible. Personally, I never want to let a login last for more than a day. But again there is a trade off here of security vs. usability, and no one likes having to login over and over again. Side note, two factor authentication through SMS becomes quite useless when the attacker is literally holding the user's phone. To that end, I don't think SMS auth adds any protection at all for mobile apps, and I have a laugh whenever an app texts me a code on the device I am logging in from.&lt;/p&gt;

&lt;p&gt;Another concern for mobile apps in particular is code security. Typically mobile apps are deployed via app stores, and available for download by anyone in the world. Maybe your app requires a login to do anything, so you don't care if unauthenticated users install and run it. However, you should consider what a malicious "black hat" attacker can do with your app bundle. As an attacker, I can take your apk or ipa file, unzip it, and start inspecting the bundle contents for vulnerabilities. I might attempt to decompile and reverse engineer your binary code files. I could also deminify and tamper with your hybrid app javascript code. Doing so means I could read any hard coded secrets or endpoints, or "fake" a login to move past that screen. This is where "security by obscurity" fails, and why it's so important to have proper encryption setup to protect your data and endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;DISCLAIMER&lt;/em&gt;:&lt;/strong&gt; Black hat practices are not something I have a lot of experience with, and I'm writing this section hypothetically as if I were a malicious agent, for the sake of argument and fun. I would never attempt this on someone else's compiled application! ✌️😊&lt;/p&gt;

&lt;p&gt;When writing your application code, consider it vulnerable. Always strive to Keep It Simple, Stupid™. A popular opinion these days is the less code you have, the better. However, you should also be careful when trying to AVOID reinventing the wheel. If you are bringing in third party frameworks, do your due diligence and READ THE SOURCE CODE! If you can't view the source before baking it into your app, that is akin to taking candy from a stranger. You are putting a lot of trust in these third party strangers to give you something sweet that won't disable or kill you, or worse - attempt to steal your identity and information.&lt;/p&gt;

&lt;p&gt;Last thing I want to touch on briefly is social engineering. This is definitely the hardest thing to protect against as a developer. We can follow all the security best practices in the world and have good encryption put in to protect our apps, but when a user gets scammed and leaks a password, all bets are off. Once an attacker has valid credentials, they are freely able to use the app as if they were someone else.&lt;/p&gt;

&lt;p&gt;For internal business productivity apps, it is really important then to design good authorization mechanisms. Make sure you understand the difference between authentication and authorization, and make sure you're doing both right. You should meticulously discriminate on who can see what data. Make sure employees only have access to data that they need to do their job! And if you can, make sure your organization has good training and communication in place to help your users recognize and avoid social engineering scams.&lt;/p&gt;

&lt;p&gt;For all you other mobile devs out there, I hope you learned nothing from this article, and rather that it reinforced some obvious things you already knew. It is all too easy to let security get swept under the rug on a project, and I've certainly been guilty in the past of focusing on the more fun parts. Security is a big topic and an area where the industry at large needs to continually keep improving. As security practices evolve, so do hacking techniques. Put another way, as hackers get better at cracking systems, we must also change our approach to security. It is almost like a dance, or a hamster in a wheel; it is a continuous struggle to design systems where digital information is safe. As a society, we are likely going to keep seeing major scale data breaches occur. And again, as developers it is in our best interest to keep abreast of security concerns, keep security in the forefront of our minds, and design our systems as securely as possible.&lt;/p&gt;

</description>
      <category>security</category>
      <category>mobile</category>
      <category>infosec</category>
      <category>hacking</category>
    </item>
    <item>
      <title>Machine Learning in Mobile Applications</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:23:05 +0000</pubDate>
      <link>https://dev.to/leading-edje/machine-learning-in-mobile-applications-3541</link>
      <guid>https://dev.to/leading-edje/machine-learning-in-mobile-applications-3541</guid>
      <description>&lt;p&gt;Machine learning is rapidly integrating into the consumer end-user experience. Netflix routinely recommends shows I may enjoy based on my viewing history. Snapchat's filters are driven by complex facial recognition and evaluation algorithms. Facebook can identify which of my friends are in a photo with uncanny accuracy.&lt;/p&gt;

&lt;p&gt;The potential impact of machine learning is not bound by industry or trade. Health care, agriculture, media / entertainment, household appliances, aerospace, and defense are all being explored and enhanced by machine learning.&lt;/p&gt;

&lt;p&gt;The most common architectures found in today's machine learning implementations are cloud-based. Voice assistants such as Siri and Alexa require connection to powerful servers, and use massive amounts of computational power and data streaming. However, a new trend is emerging to optimize machine learning algorithms and move the computation onto the mobile device.&lt;/p&gt;

&lt;p&gt;The shift towards performing machine learning tasks on mobile devices has been heralded by Apple's &lt;a href="https://developer.apple.com/documentation/coreml"&gt;CoreML&lt;/a&gt; library for iOS 11, as well as Google's release of &lt;a href="https://www.tensorflow.org/mobile/tflite/"&gt;TensorFlow Lite&lt;/a&gt; (supports both iOS and Android). Qualcomm is also making waves on this trend. Their &lt;a href="https://www.qualcomm.com/products/snapdragon/machine-learning"&gt;Snapdragon processors&lt;/a&gt; are designed from the ground up to harness the power of machine learning on smartphones and tablets. They also offer an &lt;a href="https://developer.qualcomm.com/software/snapdragon-neural-processing-engine-ai"&gt;SDK&lt;/a&gt; for supported Android devices. Developers can now take advantage of these libraries and integrate AI into their mobile applications without needing to connect to the cloud.&lt;/p&gt;

&lt;p&gt;With these and other recent advances, we are witnessing the beginning of an exciting new era of smartphone app intelligence. Machine learning is becoming more efficient and ubiquitous on mobile devices.&lt;/p&gt;

&lt;p&gt;Mobile applications that perform machine learning on device are more reliable. When internet connection becomes intermittent or non-existent, these apps can still provide value to users and perform sophisticated tasks without relying on the cloud. This makes the applications much more dependable.&lt;/p&gt;

&lt;p&gt;Many people have raised privacy concerns in this modern era of technological advancement with our newfound dependence on the internet. People today are concerned about issues like identity theft and mass surveillance. By performing machine learning tasks locally within mobile apps, data security stands to be greatly improved. All of the input data for a machine learning model can now be accessed and analyzed on the mobile device itself. Instead of the data being routed through various network switches and external servers, it can now remain safely on the device which greatly improves security.&lt;/p&gt;

&lt;p&gt;As non-technical end users become aware of the potential for AI, consumer expectations are rapidly outpacing what the current AI / machine learning platforms are actually capable of delivering. For example, the release of the &lt;a href="https://www.apple.com/homepod/"&gt;Apple HomePod&lt;/a&gt; was met with widespread criticism. Rather than praising its ability to analyze listening habits and provide suggestions for new music, many users criticised it for lacking the ability to call an Uber or differentiate between voices of different household members. Developers, UI/UX designers, project managers, and business leaders alike should all be cognizant of the rising user expectations, and strive to improve products and tools by exploring the possibilities of machine learning.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Intro to Augmented Reality</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:22:53 +0000</pubDate>
      <link>https://dev.to/leading-edje/intro-to-augmented-reality-564j</link>
      <guid>https://dev.to/leading-edje/intro-to-augmented-reality-564j</guid>
      <description>&lt;p&gt;&lt;strong&gt;aug·ment&lt;/strong&gt;&lt;br&gt;
(verb)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;make (something) greater by adding to it; increase.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Augmented Reality is an evolving set of technologies with the potential to improve our lives in a variety of ways. To define it succinctly, AR is the rendering of digital information superimposed onto one's view of the physical world. You've seen it before; a prime example being the down markers on football TV broadcasts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--983Aweks--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bnhi16jxv05ij1wmyir6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--983Aweks--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bnhi16jxv05ij1wmyir6.png" alt="Down Markers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why care about AR?
&lt;/h2&gt;

&lt;p&gt;Until recently, the prospect of seamlessly blending the physical and digital anywhere you want has remained in the realm of Science Fiction. AR has in fact existed in various forms dating back to the 1960s, but none of the implementations of the past have been portable or very practical for consumer use. However, we are now witnessing this technology become mainstream, due primarily to the proliferation of mobile hardware. The successive iterations of the smart phone market have driven us towards having a compact, low cost, powerful set of sensors and display residing in nearly everyone's pocket. We are at an unprecedented level of hardware saturation, enabling some really compelling AR applications, and we haven't even seen the endgame yet. Will wearables replace all our smartphones? What does the next generation of mobile computing look like?&lt;/p&gt;

&lt;p&gt;Unwinding the future possibilities is endless and entertaining, but I digress. Right now in the current mobile app landscape, AR is getting big! Lots of cool apps exist today that utilize computer vision and tracking algorithms to do all manner of neat things. If you haven't seen these, take a few moments to check out some links:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=vDNzTasuYEw"&gt;IKEA Catalog App&lt;/a&gt; - place and view furniture pieces in your living room&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@markracette/snapchat-s-future-lies-in-augmented-reality-afbfe1834e7a#.icg2333u0"&gt;Snapchat&lt;/a&gt; - face tracking with fun meme-ery&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=U6CpD4hVmqc"&gt;HoloLens&lt;/a&gt; - featured at the 2016 Build conference running a Vuforia app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just to name a few standout examples. While there are many apps already applying this technology, there is still plenty of room left for innovation and creative new ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diving into AR Development
&lt;/h2&gt;

&lt;p&gt;I first became interested in AR when I attended the &lt;a href="http://www.m3conf.com/"&gt;M3 Conference&lt;/a&gt; a few years ago, and heard a keynote presentation from Trak Lord of Metaio. I was inspired, so I looked around and found a plethora of platform options for building AR apps. From my own research, I can assert that the Vuforia SDK has the easiest learning curve today. I have used this toolkit to build one demo application for a paying client, a few internal company prototype apps, and many just-for-fun personal projects as well.&lt;/p&gt;

&lt;p&gt;Looking back I am glad I didn't invest much time learning the Metaio SDK. They were acquired by Apple in 2015, and have since shut down all public support. Apple has been very quiet about the acquisition, not releasing any news about what they are doing with the technology. Clearly they are looking to innovate in the AR space and are doing some internal R&amp;amp;D right now. Personally, I am excited to see what they come up with, and wonder what built in AR features the next iPhone may have!&lt;/p&gt;

&lt;h2&gt;
  
  
  Vuforia History
&lt;/h2&gt;

&lt;p&gt;Vuforia began as an in-house R&amp;amp;D project at Qualcomm, a telecommunication and chip-making company. At the time, the company was looking for computationally intensive apps to showcase the prowess of their Snapdragon mobile processors. Nothing flashy enough for them existed on the app market, so they decided to push the boundary and create some new software on their own. They built the Vuforia base SDK and launched it as an open source extension of the AR Toolkit.&lt;/p&gt;

&lt;p&gt;Since the initial inception, Qualcomm &lt;strong&gt;augmented&lt;/strong&gt; their base SDK with a variety of tracking enhancements and other proprietary features. To sustain the project long term, they migrated away from the open source model, and they eventually sold ownership of the library to software company PTC. Unlike the sale of Metaio's SDK to Apple, this transfer kept support very much alive for its development community. Since then, Vuforia has grown to be (one of) the premier Augmented Reality SDKs, used by hundreds of thousands of developers worldwide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Tools
&lt;/h2&gt;

&lt;p&gt;Apps using the Vuforia framework today require a license key. Deployment licensing options start at a reasonably low price, and prototype "Starter" apps can be developed free of charge! You can create an unlimited number of prototype applications at no cost via their &lt;a href="https://developer.vuforia.com/"&gt;Developer Portal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Building custom AR experiences necessitates thinking in 3D, and having great tools goes a long way in easing that burden of complexity. The Unity 3D game engine is a very intuitive environment for editing scenes in 3D, and it's scripting engine uses C#, making it a fantastic choice for developers who are versed in .NET. To me, the best part of the Vuforia SDK is the Unity plug-in. It enables you to build AR applications, &lt;strong&gt;without writing any code at all&lt;/strong&gt;, that can run on pretty much any mobile phone or tablet.&lt;/p&gt;

&lt;p&gt;Putting together a marker-based AR app is incredibly easy with these tools. If you have no experience working in Unity, there will be a learning curve involved. A good primer for understanding the Project, Hierarchy, Scene, and Inspector panels can be found &lt;a href="http://docs.unity3d.com/Manual/UsingTheEditor.html"&gt;here&lt;/a&gt;. Once you are familiar with the tools, building AR apps is easy and a lot of fun! Below is a short list of steps to exemplify how quickly you can get an AR app up and running on a webcam enabled machine. Not included here are the steps for deployment to a mobile device (a topic for another day).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create New Project in Unity (use 3D settings).&lt;/li&gt;
&lt;li&gt;Delete Main Camera from the scene.&lt;/li&gt;
&lt;li&gt;Import Vuforia Unity Package (downloaded from the Developer Portal).&lt;/li&gt;
&lt;li&gt;Import target database (downloaded from the Developer Portal).&lt;/li&gt;
&lt;li&gt;Add two prefabs to the scene from Vufora Assets: &lt;strong&gt;ARCamera&lt;/strong&gt; and &lt;strong&gt;ImageTarget&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;ARCamera&lt;/strong&gt; in the scene hierarchy. In the Inspector Panel, paste in the &lt;strong&gt;App Key&lt;/strong&gt; (created via Developer Portal), then &lt;strong&gt;Load&lt;/strong&gt; and &lt;strong&gt;Activate&lt;/strong&gt; image target database (two checkboxes).&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;ImageTarget&lt;/strong&gt; in the scene hierarchy. In the Inspector Panel, select from the dropdowns for Database and Image Target (stones).&lt;/li&gt;
&lt;li&gt;Import a 3D model asset to the project (drag and drop from file system into Unity).&lt;/li&gt;
&lt;li&gt;Add the model asset to the scene as a child object of the Image Target.&lt;/li&gt;
&lt;li&gt;Center and resize model as needed to cover the Image Target.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can download my completed example Unity project from &lt;a href="https://github.com/tomhartz/LeadingEDJE-AR"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r7Q1F25E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/farwukczmbl5nl5ack7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r7Q1F25E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/farwukczmbl5nl5ack7n.png" alt="AR Tom"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ar</category>
    </item>
    <item>
      <title>CI &amp; CD for iOS Apps</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:21:13 +0000</pubDate>
      <link>https://dev.to/leading-edje/ci-cd-for-ios-apps-3n21</link>
      <guid>https://dev.to/leading-edje/ci-cd-for-ios-apps-3n21</guid>
      <description>&lt;p&gt;Continuous Integration and Continuous Delivery have become pillars of modern development. Reporting breaking changes back to your dev team quickly can improve both the quality and the speed at which you deliver software. Likewise, automating the release pipeline for your deliverables cuts down on redundant labor and allows you to focus more time on meaningful work. This all applies in the realm of mobile application development, but there are some special considerations to account for with the iOS platform.&lt;/p&gt;

&lt;p&gt;Building iOS applications requires Mac hardware. This means your development team will need MacBooks, but it also means to do CI/CD you will need a server running macOS. Recently on a project, I worked through setting up a Mac Mini machine as a Bamboo build agent to perform CI/CD tasks for both mobile platforms (Android build plans can be executed on any type of agent: Windows/Linux/Mac). In this article, I will share some of the issues I encountered as well as some of the concrete build plan steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Branch Detection
&lt;/h2&gt;

&lt;p&gt;A standard CI setup is going to start with Branch Detection. Every time new code is pushed to a feature branch, the unit tests are executed against the changes. This part of your pipeline does not have to be restricted by platform, even if you are building a native iOS app and have a suite of XCTest cases in Swift. XCTest cases supposedly can be made to  &lt;a href="https://riis.com/blog/swift-unit-testing-ubuntu/"&gt;run in Linux&lt;/a&gt;, although I have never personally tried it. It is probably simpler and easier to set up this part on a Mac agent with Xcode anyway, and the other steps WILL require it. Branch Detection build plan steps are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Source Code Checkout&lt;/li&gt;
&lt;li&gt;Run Unit Tests&lt;/li&gt;
&lt;li&gt;Check Code Coverage&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Merging the feature branch into development/master should require a passing test suite and one or more code review approvals.&lt;/p&gt;

&lt;h2&gt;
  
  
  UI Testing
&lt;/h2&gt;

&lt;p&gt;Typically after merging one or more feature branches, the next step for CI/CD is to create a build for automated UI tests and/or manual regression testing. Automated UI testing for iOS has some significant challenges! Using a device simulator is easier to manage, but you cannot install any given .ipa onto it, it has to be compiled specifically for the simulator CPU architectures.&lt;/p&gt;

&lt;p&gt;iOS Device CPU architectures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;arm64 is the current 64-bit ARM CPU architecture, as used since the iPhone 5S and later (6, 6S, SE and 7), the iPad Air, Air 2 and Pro, with the A7 and later chips.&lt;/li&gt;
&lt;li&gt;armv7s (a.k.a. Swift, not to be confused with the language of the same name), being used in Apple's A6 and A6X chips on iPhone 5, iPhone 5C and iPad 4.&lt;/li&gt;
&lt;li&gt;armv7, an older variation of the 32-bit ARM CPU, as used in the A5 and earlier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;iOS Simulator CPU architectures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;i386 (i.e. 32-bit Intel) is the only option on iOS 6.1 and below.&lt;/li&gt;
&lt;li&gt;x86_64 (i.e. 64-bit Intel) is optionally available starting with iOS 7.0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This unfortunately means you cannot test an app bundle using a simulator, and then promote the same "artifact" for release. For iOS you have to do physical device testing, from which you can then promote an app bundle to production. Keep in mind that automated testing on tethered physical devices will require more overhead to maintain and keep the CI pipeline running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build
&lt;/h2&gt;

&lt;p&gt;Producing an .ipa file from an automated build can be done in two steps:&lt;/p&gt;

&lt;p&gt;1. Create an archive and sign&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;security unlock-keychain -p $PASSWORD login.keychain

xcodebuild -workspace 'MyProject.xcworkspace' -scheme 'MyProject' -configuration Debug -archivePath ./archive/'MyProject.xcarchive' clean archive -UseModernBuildSystem=NO DEVELOPMENT_TEAM=########## CODE_SIGN_IDENTITY="iPhone Developer: Tom Hartz (##########)" PROVISIONING_PROFILE='MyProject development profile' OTHER_CODE_SIGN_FLAGS='$HOME/Library/Keychains/login.keychain-db' CODE_SIGN_STYLE=Manual
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;2. Export the archive into an app bundle (.ipa)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xcodebuild -exportArchive -archivePath ./archive/MyProject.xcarchive' -exportPath 'archive/ipa' -exportOptionsPlist Development.plist
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Development.plist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;compileBitcode&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;false/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;method&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;development&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;provisioningProfiles&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.leadingedje.myproject&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;MyProject development profile&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After creating an app bundle, your build plan can save it as an artifact in Bamboo, and also upload it to TestFlight, HockeyApp/App Center, etc. for internal deployment and testing.&lt;/p&gt;

&lt;p&gt;Artifact Promotion &amp;amp; Release to Prod&lt;/p&gt;

&lt;p&gt;After regression testing has been signed off by your QA team, you will want the final step of your CD pipeline to pick up this artifact and release it to production. A release plan in Bamboo would be as follows:&lt;/p&gt;

&lt;p&gt;1. Download Artifact&lt;br&gt;
2. Modify for release&lt;br&gt;
   a. Unzip .ipa bundle&lt;br&gt;
   b. Replace dev provisioning profile with production&lt;br&gt;
   c. Delete existing code signature&lt;br&gt;
   d. Perform any custom app configuration (set Prod API url, etc.)&lt;br&gt;
   e. Resign bundle using production entitlements&lt;br&gt;
   f. Re-Zip bundle&lt;br&gt;
3. Upload to Apple (App Store Connect) &lt;/p&gt;

&lt;p&gt;Here is a shell script example I wrote that performs all of step 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "begin iOS release build..."

mkdir ipa

cp MyProject.ipa ipa/MyProject.zip

echo "copying provisioning profile..."

cp $HOME/Downloads/MyProject_Distribution_Provisioning_Profile.mobileprovision ./ipa

echo "unzipping ipa..."

cd ipa

unzip MyProject.zip

echo "unlocking keychain..."

security unlock-keychain -p $PASSWORD login.keychain-db

echo "replacing provisioning profile..."

cp "MyProject_Distribution_Provisioning_Profile.mobileprovision" "Payload/MyProject.app/embedded.mobileprovision"

echo "removing existing code signature..."

rm -rf Payload/MyProject.app/_CodeSignature/

echo "signing ipa..."

codesign --entitlements Entitlements.xml -f -s "iPhone Distribution: Leading EDJE LLC (##########)" Payload/MyProject.app

echo "zipping app bundle..."

zip -qr MyProject.ipa Payload/

echo "iOS build done!"

exit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Entitlements.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;application-identifier&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;##########.com.leadingedje.myproject&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;aps-environment&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;production&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;beta-reports-active&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;com.apple.developer.team-identifier&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;##########&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;get-task-allow&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;false/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  DIY vs. Cloud CI
&lt;/h2&gt;

&lt;p&gt;My experience and approach in this article is focused on an in-house custom solution for CI/CD in Bamboo, but there are third party services available which can provide some of these build actions for you. You may be able to subscribe to one or more of these services to avoid having to buy Mac hardware to run your builds and test suite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/device-farm/"&gt;AWS Device Farm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bitbar.com/"&gt;Bitbar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.browserstack.com/app-automate/xcuitest/get-started"&gt;BrowserStack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.buddybuild.com/"&gt;Buddy build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.perfecto.io/"&gt;Perfecto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://saucelabs.com/devices"&gt;Sauce Labs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;DISCLAIMER: I have not tried any of these services, so your mileage with them may vary. While they may simplify things somewhat, I expect you will still need to configure them quite a bit with custom build steps and options, depending on the specifics of your iOS project.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>mobile</category>
      <category>ios</category>
      <category>devops</category>
    </item>
    <item>
      <title>Making the Case for Software Testing</title>
      <dc:creator>tom-hartz</dc:creator>
      <pubDate>Mon, 18 May 2020 20:21:01 +0000</pubDate>
      <link>https://dev.to/leading-edje/making-the-case-for-software-testing-2oko</link>
      <guid>https://dev.to/leading-edje/making-the-case-for-software-testing-2oko</guid>
      <description>&lt;p&gt;I was recently talking with a skeptic of software testing. In his view, writing code to test other code seems dubious. Why would you want to create and maintain a bunch of extra code to prove your original code does what it should? His argument was that testing was unnecessary and not worth the effort (you're going to manually test it anyway).&lt;/p&gt;

&lt;p&gt;I can see his point of view, even if I don't agree with his sentiment. I think he was coming from a place of bad habit, having never written any tests for any of the application code he's ever built. From that point of view, testing can seem like a daunting task, requiring a ton of extra effort for no tangible benefit.&lt;/p&gt;

&lt;p&gt;There are many kinds of software tests you can write, and all of them provide benefits. The longer the life expectancy of an application, the more benefit tests provide. You may not be the sole programmer on a project for its lifetime, and having specified tests is actually an effective form of documentation.&lt;/p&gt;

&lt;p&gt;Unit Testing involves writing code to call individual functions. While application logic may contain needed complexity to solve business problems, the tests should be pure and simple. By following the pattern of AAA (Arrange, Act, Assert, a.k.a Given/When/Then) unit tests are clear and easy to follow. Unit Tests validate that business logic executes correctly and returns expected outputs under different scenarios of inputs. Adding unit tests is somewhat tedious, but with practice they become so easy to write that there is no good excuse for skipping them. They provide proof that the code is well built and individual units of code work as expected.&lt;/p&gt;

&lt;p&gt;Integration Tests are similar, but instead of mocking dependencies you inject the concrete components of your application and test how they interact. This kind of testing also can validate that the software behaves in a reasonable amount of time, and has good performance in all cases.&lt;/p&gt;

&lt;p&gt;UI Tests are usually harder to write and likely to break over time with application changes. But they can replace or reduce the amount of manual regression testing you or your QA team has to perform.&lt;/p&gt;

&lt;p&gt;I often hear from programmers who are working on personal projects, that they have 0 tests. I think it is something people often tend to skip on personal projects because it feels like work, and developing the software functionality itself is more fun. I think as we develop better tools for building software, testing will become even easier to the point where everyone's personal projects will include tests. There are tools being developed like &lt;a href="https://github.com/randoop/randoop"&gt;randoop&lt;/a&gt; to automatically generate unit tests!&lt;/p&gt;

&lt;p&gt;I haven't said anything about Test Driven Development (TDD) yet. TDD is the practice of writing tests BEFORE you implement any code for any given new feature. I am not a TDD zealot; I think it is mostly a useful practice for defect fixes. When you get a bug report and don't yet know the cause, it is usually pretty easy to write a failing test at some level to reproduce the bug. From there, you can step through and debug and find the right refactor to fix the defect and pass the test. This is an efficient way to work through the bug and provide coverage to prove the correct behavior from there on. However, in my experience doing green-field development, writing tests first is a struggle. I prefer to at least design my components and interfaces from a high level before adding test cases.&lt;/p&gt;

&lt;p&gt;Bottom line, I think a testing suite provides tremendous value to an application. If I am joining a project I would always prefer that codebase to have some form of testing in place as a way for me to understand and follow the code. It also gives me a sanity check that any changes I commit do not adversely affect other parts of the app (ideally as part of an automated build CI pipeline). To non-programmers and stakeholders, test coverage gives confidence that the software meets the requirements, and is usable and stable. Software testing is absolutely a worthwhile endeavor!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>codequality</category>
    </item>
  </channel>
</rss>
