Sprint 5 Retrospective – Testing Our PouchDB Service

Unfortunately my team and I were unable to meet the goals we set for ourselves at the beginning of this sprint cycle. The biggest issue we’ve been facing is writing tests for our offline storage service which implements pouchDB. In researching how to write meaningful  unit tests in Angular for services that implement pouchDB, we have found few helpful resources. The pouchDB API, which can be found here, provides little documentation on this subject so we have been forced to refer to git-issue pages and various tutorials. The issue with these resources is they tend to be somewhat outdated and don’t exactly match our particular use case.

My team and I have referred to the pouchDB API when it came to writing methods for our offline storage service. Our methods are pretty straight forward as they implement standard pouchDB functions such as get(), put(), and remove()  for getting, adding, altering, and deleting data from the offline storage database. So, for the most part, we believe our methods are correct and function as intended. However, in order to be sure our methods are functioning correctly, we need to write meaningful unit tests in Angular. The first test we wrote just checks to make sure the pouchDB in-browser database is successfully created. This test passed and when we looked at the web page Karma opens when the tests run we can open up the developer tools and see that our database is in fact created. This is depicted in the screen shot below:

Screenshot 2018-04-18 10.51.16

Although we can see that our pouchDB in-browser database is instantiated, we run into a mess of problems when trying to call pouchDB functions. For instance, when trying to add elements into the database we use pouchDB’s “put()” function and pass in a string which then gets parsed as a JSON object. To test this method we created a mock patient object, in JSON format, at the beginning of our test class and tried confirming it was being successfully added by checking the Karma test page in the browser. I should mention that the process of debugging has been quite difficult when trying to figure out why tests aren’t passing because many of the error messages  generated after tests fail seem to lack essential descriptive information. I say this because we are rarely given specific line numbers from our service indicating where the errors occurred. Instead, we seem to get a bunch of references to files that we aren’t concerned about. I feel that this may be partially due to our lack of experience in writing unit tests in Angular.

I was actually able to make some progress today in testing the “addDoc()” method for our offline storage service. Previously, we had gotten the test to pass but I was left unconvinced that it was actually working as intended because I could not see any data being stored in the in-browser pouchDB database. After some trial and error I was able to get the method to work and physically see the data in our pouchDB database. Here is a screen shot depicting the data that was successfully added:

Screenshot from 2018-04-18 21-02-57

Now that I understand how to get mock data into our offline storage database, I will relay this information to my team and we should be able to make some real progress as this has been one of the main issues holding us up.


Apprenticeship Patterns: Be the Worst

At first glance, I thought this particular apprenticeship pattern seemed a bit absurd. The reason I say this is because I couldn’t imagine why anyone would actually want to “be the worst” in terms of skill level and knowledge on a team of seasoned software developers. However, after reading the rest of what the authors had to say in this pattern it started to make a lot of sense. This pattern reiterates some of the ideas presented in other patterns such as “The Deep End” and “Stay in the Trenches.” Essentially, the authors explain that it is more beneficial to be a “small fish in a big ocean” rather than a “large fish in a small pond.” What this means is that by taking on more difficult projects and/or working with more experienced developers you will provide yourself with more learning opportunities and walk away with a number of invaluable skills that you will pick up from your more experienced colleagues as well as your own personal experiences.

The authors note that this idea might seem crazy as it clashes with cultural norms that seem to advocate the idea that one should try to obtain the highest-paying position with the most superiority as soon as possible. They talk about how adhering to this cultural norm can curtail ones own self-development process by getting stuck in a position that lacks any real challenge. Another thing in this pattern that I found encouraging was the testimonials from various software developers describing their own experiences of “being the worst.” While you’d think that being the least skillful and/or knowledgeable team member would be an undesirable experience, all of the testimonials in this pattern seem to illustrate positive experiences of self-improvement and success.

At the end of this pattern the authors suggest that software apprentices should try to reach out and observe teams that operate at a high skill level in attempt to “be the worst” but in way that guarantees personal-growth. I think this apprenticeship pattern has provided me a new sense of confidence going forward. I’ve learned that it is completely fine to “be the worst” in a team of experienced software professionals because when you are, you have the largest number of learning opportunities that help push you further down the “long road” of becoming a true software craftsman.

Sprint 4 Retrospective – Narrowing our Scope

At the beginning of this sprint cycle my team and I thought we had a pretty good handle on what we needed to accomplish and how we were going to do it. In the previous sprint cycle we had figured out how to instantiate a pouchDB in browser database as well as add elements and get them back through the console. To test whether we could get pouchDB working within the ng2-amrs application we added some code the app.component.ts file. Once we were sure that pouchDB could work in the application we moved forward in writing the pouchDB offline storage service. However, we were trying to incorporate open-mrs api calls in our offline storage service which proved to be much more complicated than we originally though. To remedy this problem we decided to break it into smaller pieces and Conor drew up a diagram in balsamic to help us not over think what we needed to accomplish. Here is the diagram Conor made:

 Offline Data Module Architecture

In this diagram my team’s responsibility is the “Offline Data Storage Service.” Instead of trying to do everything at once, we decided we just needed to write a service that will store JSON objects in an in-browser database. By narrowing the scope of what we needed to get done to one task we have been able to make more meaningful progress.

During our team meetings we were able to get started in writing an add method for our offline storage service as well as corresponding unit tests. Through writing this method and it’s corresponding unit tests we found that pouchDB databases use JSON objects by default making our job a little easier. We have not pushed any new code onto our group’s GitHub page but that will be one of the first steps we take in starting the next sprint cycle.

In our last team meeting we were able to get everyone caught up on where we were at in the project and assign specific tasks to each group member going forward. After narrowing our scope down we decided that the main methods we needed to focus on for our offline storage service included add, put, delete, and clear. The add method will store elements in JSON format in the pouchDB database. As for the put method, it should take in the id of an element already stored in the database and alter the information of that element. Finally, the delete method will take in the id of an element in the database and remove the element, this method will also return the JSON object that was deleted. We also discussed implementing a clear method that could erase all data stored in the pouchDB database but we have not decided whether or not this function will be necessary to accomplish our goals.

Moving forward, my team and I will have to contact the Ampath developers and ask if they agree with the direction we are heading in. We will also need to communicate with other teams to make sure that our service can coexist/ be implemented in the other teams’ code. If everything goes as planned, we should have a functional offline storage service by the end of the next sprint cycle and we should also be able to start piecing together our piece of the project with other teams’.

Apprenticeship Patterns: The Long Road

In this section of Apprenticeship Patterns the authors discuss what a developing software professional can expect from his or her career choice in the long run. The talk about how becoming a software craftsman does not happen over night and if someone hopes to master the the craft of software development they should be aware that they are in for a life long journey of learning and self-improvement. The authors describe the context for this pattern by discussing how the values of modern society sometimes conflict with the the practices necessary to become a master in the software development craft. They talk about the values of people in modern society consisting of “overnight celebrities, rising stars, material wealth, and quick results.” However, in the field of software development “quick results” can often lead to poorly written and/or bug ridden code. Also, the authors make a point in describing the problem that exists here being that modern values might compel a developing software professional to take the highest paying job they can find and quickly race towards their first promotion in an attempt to stop programming and start managing other people and making more money.

While higher paying salaries are definitely a key factor in propelling individuals to take up software development, the authors suggest this shouldn’t be the main contributor when it comes to making career decisions. Their solution to this problem entails thinking ahead and keeping in mind what will bring you the most joy and the highest sense of achievement. At the end of this pattern, in the action section,  the authors provide a thought experiment in which they ask you to think about where you will likely be in 10 years and what you will be doing. They then ask you to do the same thing for 20, 30 and 40 years from now and write down all of your answers. By doing this you may be able to gain some insight on what types of jobs/positions will be best suited for your own personal goals. I thought this was a great exercise and I found this pattern to be quite insightful. I also definitely agree with the authors on the idea that modern values don’t usually align with successful software development practices. After reading this pattern I believe that I will have more confidence in making career choices in the future through partaking in the thought experiment and referring to my answers when I’m faced with difficult choices within my professional career.

Sprint 3 Retrospective – Implementing Offline Storage

Similar to the last sprint cycle, this sprint consisted mostly of research rather than actually writing code. Right at the beginning of this sprint cycle my team and I faced some issues regarding getting pouchDB installed in the ng2-amrs application. Not every team member ran into the same issue though. In fact, Ben was able to install PouchDB into the application first try without any complications. As for myself and my other team members, upon installing pouchdb using the command “npm install pouchdb @types/pouchdb” some of the other dependencies were erased causing the application to throw a bunch of errors when we were trying to start it. To fix this problem I reinstalled all the dependencies in the order listed in the Read-Me file. After that I was able to run the application without errors and ensure that pouchDB was still installed as a dependency.
After we got pouchDB successfully installed the next step was to figure out how to instantiate a pouchDB instance to store data locally. After a lot of trial and error I found that importing pouchdb into the app.component.ts file and writing code to make a new pouchdb database in the constructor allowed me to see the new database when I started the app. To see that the database was created, I had to open up the browser’s developer tools and go to application resources. After that I tried adding elements to the pouch database and getting them back. The nice thing about pouchDB is that the commands associated with pouchdb are pretty straightforward and it uses json objects by default. To add new elements to a pouchdb database named “db” you simply write “db.add(…)” with the element you want to add inside the parentheses. Then to retrieve that data element you can simply write “db.get(…)” with the element’s id inside the parentheses.
This sprint cycle also gave way to a whole new issue that my team will have to deal with in the upcoming sprint. In my last retrospective blog post I talked about pouchDB’s asynchronous capabilities with any server running couchBD. We learned this sprint cycle that the open-mrs server is not compatible with couchDB so we will be unable to apply pouchdb’s asynchronous functionality to this application. This may be a pretty big set back as we now have to develop our own service to ensure that data stays up to date between the open-mrs server and our in-browser pouchdb database.
Moving forward we will need to reach out to AMPATH and figure out how they want us to implement the offline storage component. Some of the things we will need to consult with them about are how the code should be structured, whether or not we need more than one pouchdb instance, and how we should synchronize the storage between the in-browser pouchdb database and the open-mrs server. As far as code structure goes, we need to figure out if where we instantiate the pouchdb instance is a safe place or not. I was thinking that we may want to write an offline storage module that handles all the imports and pouchdb logic and then import that module into the app.component.ts file. Next, we need to figure out if user credential information should be stored in a separate pouchdb database than the patient data to possibly provide better security. We will also be consulting with some of the other teams to try an figure this out. Finally, since we cant make use of pouchdb’s asynchronous functionality, we need to talk to the people at AMPATH to get some advice on how we should synchronize offline storage with their open-mrs server.
Another thing I did this sprint cycle is I started to put together an offline storage service that will be used to store patient records in our pouchDB database. The code I wrote for this can be found here: https://github.com/cpruitt1230/ng2-amrs/tree/master/src/app/offline-storage. I based some of this coded off of the advice given from one of the AMPATH developers on slack. Unfortunately I have not been able to test this code which should pull patient data from the open-mrs server and store that data in a pouchdbd database in the browser. Testing is going to be another issue that my team and I will have to address this sprint cycle as none of us are too familiar with how to write tests in angular not to mention tests that will ensure the in-browser database is storing what it’s supposed to. I’m looking forward to this next sprint as I feel like we are actually making some progress and hopefully we have a lot more to show for the end of next sprint now that we know how to get a pouchdb instance up and running.

Apprenticeship Patterns: Confront Your Ignorance

The context for this pattern, as described by the authors, is that you have found gaps in you skill set that are effecting your everyday work. The problem here is that your knowledge of essential tools and concepts is lagging behind that of your coworkers but you are expected to already have this knowledge as a prerequisite for being a productive member of the team. The authors explain that this particular pattern goes hand-in-hand with the “Expose Your Ignorance Pattern.” They stress the importance of adopting both of these patterns simultaneously as just adhering to one or the other can present problems of their own. For instance, by only exposing your ignorance and never confronting it you may end up in a constant state of ignorance and being overly dependent on other team members when it comes to completing essential tasks relating to the project at hand.  On the other hand, if you only confront your ignorance without ever exposing it you may be missing out on valuable insights your team members could provide you not to mention the fact that you may spend too much time trying to learn specific concepts that could have been easily explained to you by a team member who already has the knowledge you are seeking. According to the authors, the solution to this problem is to “strike a delicate balance” between these two patterns in order to ensure you are learning the essential skills necessary for your role without wasting to much time and allowing you to be as productive as possible.

I found this pattern to be quite relatable in my current role as a Security Analyst. When I first joined the team I had very little knowledge when it came to essential information security concepts. For example, in security it is crucial to have a fundamental understanding of how the different layers in the OSI network model function. This can be quite overwhelming at first considering that each of the seven layers have different functionality along with a multitude of associated protocols that they must adhere to. Luckily my team has been really supportive in helping me gain the necessary knowledge and skills by giving me practice problems and either providing me the resources necessary to learn essential skills or pointing me in the right direction to where I can find helpful resources. I think up to this point I’ve been able to maintain a healthy balance of exposing and confronting my ignorance but the advice provided in this pattern will definitely be useful going forward.


Sprint 2 Retrospective – Research and Design

For this sprint cycle my team and I focused on how we could implement offline capability for the ng2-amrs project. We came up with some designs using balsamiq and researched what tools we could use for the backend and storing data offline. One of the contributors form AMPATH suggested that we look into a tool called PouchDB which is an open-source JavaScript database. What makes PouchDB so useful is that it can be used to store data locally so users have access to application data even when they are offline. After doing some reading and completing the tutorial provided on the PouchDB site, my team members and I decided it would be best to move forward working on the backend of the offline module using PouchDB to store important data which could be accessed offline.

Shane and I worked together last week in doing the PouchDB tutorial. We first had to download the PouchDB codebase which actually proved to be pretty simple. PouchDB can be installed through npm with either of the following commands:

npm install --save pouchdb
npm install --save pouchdb-browser

The second npm install command will only install the browser components of PouchDB. This is probably what my team and I will be focussing on since the ng2-arms application runs in the browser. One possible concern I have moving forward is that in order to keep the data up-to-date, we will have to make sure that our PouchDB database can easily sync-up with AMPATH’s servers when a wifi connection is reestablished. In the documentation, PouchDB mentions that in order implement syncing, the server needs to be compatible with PouchDB. We will need to reach out to AMPATH to ensure their production servers will be able to sync with our PouchDB database.

One of the key features of PouchDB is that it provides an “asynchronous” API. When I first read this I had no idea what it meant as I’m not all that familiar with web-developemt or the DOM design patter. However, after a little reading I started to get the idea. Essentially, the benefit of being asynchronous is that it ensures the user’s experience is not interrupted when calls are being made to the PouchDB database. If this were not the case, database calls in the browser could cause the application to stutter due to the DOM logic being blocked by those calls. The way this works is by utilizing “promise objects” to call database functions. This link provides a really useful reference for how asynchronous code works.

Along with discussing how the backend of our offline module will work, my team and I also tried to figure out how the front end UI should behave when there is no internet connection. Some of the questions we needed to answer were:

  • What type of information should be stored and displayed for individual patients?
    • For this question we want to try and store the least amount of data as possible to optimize storage.
  • What should the UI look like when the user is offline?
  • Should the UI display some sort of notification to the user when they lose their internet connection?
  • Should the user have the option to turn the application to “offline mode” in which they can chose which patients’ data should be stored while the user is offline?

We were able to gain some insight into the first question by referencing the google doc provided by AMPATH. The user stories and requirements describe which data is most important and should therefore be stored locally. For the second question, Fuverion was able to make a couple designs in balsamiq of what the UI might display when there is no intern connection.  As for the last two questions, they are still a work in progress and we will need to consult with the AMPATH developers to determine the best course of action. We will most likely do this in the beginning of our next Sprint Cycle.


Apprenticeship Patterns: The Deep End

In this apprenticeship pattern, the authors present a problem that I’m sure many rising computer science professionals have encountered early on in their careers. They describe the context of the problem as being when one feels they are stuck in a rut, falling short from their colleagues in terms of knowledge and skill. The authors explain that the only way to address this kind of issue is to dive head first into the “deep end.” What they mean by this is that the only way to advance one’s skill, knowledge and, most importantly, confidence is to take on harder tasks that are more challenging. The authors stress the fact that it is to easy to fall into a pattern of complacency and that it is essential to take risks in order to become a better software professional. One particular quote from this pattern that really stuck with me was the following:

“Risks are opportunities seen through the half-shut eyes of fear.”

I think that fear plays a huge role in decision making when it comes to computer scientists. Most notably, the fear of failure may cause a developer to hesitate in taking on a larger role within a team or committing to working on a difficult project outside of their comfort zone. I think its important to remember that even the most brilliant developers have made their fair share of mistakes and the only way to get better is to continue making mistakes because you are bound to succeed at some point if you keep trying. In this pattern, the authors give a real-life example of how this ideology can serve to benefit a developing professional by providing testimonial from a developer named Enrique Comba Riepenhausen. Enrique found himself taking on a new role at his company that entailed much more work than his previous role. Instead of becoming overwhelmed with fear and hesitation, Enrique rose to the occasion and put his best effort forward. As a result, Enrique excelled at his position and was able to construct a customized platform for his client’s needs.  Since then, Enrique describes having a plethora of opportunities including being able to travel the globe doing what he loves.

After reading this patter I decided to take the advice given by the authors in the Action section by doing the following:

  1. Make a list of the largest successful projects I have contributed to.
  2. Determine the dimensions of complexity as a means of measurement for each project listed in step 1.
  3. Create a chart with the information from steps 1 and 2.
  4. Add any new projects I take on to the chart in order to visualize the trajectory of my career.


Apprenticeship Patterns: Unleash Your Enthusiasm

I thought this section of Apprenticeship Patterns presented a fascinating take on how newcomers might fit in with their more experienced counter parts when entering the professional world of computer science. The authors describe the role an “apprentice” might want to take when working in a team of seasoned computer scientists. They explain that it is common place for newcomers to “fly under the radar” and not speak their ideas due to lack confidence in their ability to be a contributing team member. They point out that while every team may differ, teams typically benefit from having team members of varying skill levels, even “apprentices.” The authors also cite a study involving aircraft carrier crews that showed that it is healthier for teams to consist of people with different degrees of skill and experience and found that newcomers played an integral role in the team dynamic. Finally, the authors propose that newcomers should in fact “unleash their enthusiasm” in hopes that their excitement will rub off on other team members as well as keep other team members on their toes through asking many questions on why things are the way they are as well as presenting fresh ideas.

I honestly found this particular pattern to be extremely relatable as I am currently a newcomer in a security team that is made of individuals who have varying degrees of skill level, experience, and expertise.  When I first started, I admit that I was a little intimidated by all the tools that were being used not to mention all the acronyms being thrown around in meetings that I had never heard of before. However, I feel like that feeling of being overwhelmed pushed me to want to learn more about security and obtain the same kind of knowledge possessed by my coworkers while at the same time applying the knowledge I have acquired throughout the course of my college career. I also feel like I really lucked out because of the willingness of each of my team members to answer my questions and give me advise. After reading this pattern I think I will ask questions and speak up more confidently at work because now I know that it is important to bring a fresh perspective to a team.

Blog at WordPress.com.

Up ↑