Teos Technology

Explore Teos Technology services, products, insights, and ways to connect with our team.

When we approach any project, it goes without saying that we want to do it right, but what happens when the quest to discover the right solution takes over? It can prevent decision making and halt forward progress. Then you risk missed target dates, higher costs, wasted time, idle teams, and ultimately project failure. This unfortunate condition is known as “Analysis Paralysis.”

Let’s face it, no matter how thorough of an analysis you do up-front, you’re not going to find the perfect plan. Eventually you will learn something new, priorities might shift, or the technology itself could evolve. If you’re waiting until you know everything, before you start, then you will never get started. So what’s the cure for Analysis Paralysis?

You must decide. Decide to embrace the uncertainty. Decide to make decisions, despite that uncertainty. Then you must take that first step and act on your decision. You might have missteps along the way. You probably will, but two steps forward and one step back is better than no steps at all.

What exactly is software development? It’s inherently intangible. At the physical level, programming is just turning keystrokes into meaningful patterns of electrons. At the intellectual level, however, software development is a universe of its own.

A while ago, a colleague proudly proclaimed “making software isn’t engineering, it’s an art!” That really got me thinking about the validity of that statement, and what it really means. There’s software engineering and computer science, but what about art?

To find an answer, I wanted a better understanding of what exactly engineering, science, and art actually are. If you look up engineering in the dictionary, you’ll see the following:



It’s really the second definition that stands out: the application of science and mathematics by which the properties of matter and the sources of energy in nature are made useful to people. Software does indeed apply different fields of science and mathematics to make something that’s useful to people.

The latter half of the second definition of engineering is the design and manufacture of complex products. Software is assuredly a complex product, made up of many different components, and it requires careful design and manufacture.

The last part of the definition of engineering is calculated manipulation or direction. Software development, at its core, is the manipulation and direction of a computer system. The developer is directing the behavior of the computer itself.

Accordingly, software development is engineering in a number of ways. That means a software engineer is in fact performing engineering, when they design and develop software.

Having established that software development is engineering, let’s consider whether it could also be science or even art. Following the same technique, let’s dissect the definition of science:



Systematized knowledge is any information which can be arranged according to an organized system. Software development requires understanding highly specific, organized information. Hence, it falls under the second definition of science. It can be studied and learned.

Furthermore, the development of software applies scientific and mathematical laws to bring about something useful in the real world. Essentially, it turns binary numbers into practical outcomes. Consequently, it also falls under the fourth definition of science.

Software development is genuinely a science, but there’s still one more question to consider. Could developing software actually be an art? Again, turning to the definition will help answer the question. Art is defined as:



The first definition appears to fit. Software development is a skill which requires experience, study, and observation to master. It is a skill which improves with practice and refinement. It is also an occupation requiring skill and knowledge, so the third definition of art applies as well as the first.

However, it’s the fourth definition that really gets to the heart of what art truly is – a creative expression of aesthetics or beauty. When I speak of software as art, many people might think of computer graphics. While that can be art, it is using software, rather than creating software. When speaking of art in software development, I’m referring to the source code that comprises the software.

The beauty found in source code is not a visual aesthetic, but a mental aesthetic, much like other written language. Most people who aren’t developers may not realize there’s such a thing as ugly or pretty code. However, ask any developer what the ugliest code they’ve every written was, and they might blush.

Remarkably, it turns out, software development is an art. It is also science, and it's engineering. It spans all three categories, and that still doesn’t fully describe it. It is vast, complex, and beautiful.


What do you think software development is?

Take our 1 question survey.

User stories lie at the heart of the Agile process. Well defined stories can mean delivering on your commitments. Poorly written stories can lead to wasted time and carryover. However, writing "good" user stories can challenge even the seasoned software professional. With as pivotal as they are in delivering on your commitments, it's critical to get your user stories right.

So what makes for a good user story? Before we answer that, let's take a look at a simple example: a client wants a system that tracks customer information. They say they're an agile shop, and can provide you with a user story for exactly what they want. Here's what they send you.


Story 1: Manage Customers

  1. User can see customers

  2. User can edit customer details and information


​

After some initial surprise, you thank them graciously and mention that it's a little vague. They agree, and you all sit down to discuss requirements. After some creative collaboration, you have a much more complete picture of what they need.


Story 1: Manage Customers

  1. User can create a new customer

  2. User can edit the details of an existing customer

  3. Only authorized users can create new customers

  4. Phone numbers have to auto-format to (xxx) xxx-xxxx

  5. Zip codes have to be valid

  6. User can delete an existing customer if authorized

  7. User has to have permission to edit a customer

  8. Customers must have a first name, last name, address, and phone number

  9. The user can enter notes about the customer

  10. A customer can have an email address

  11. There's a list of customers that the user can view

  12. There should be an image to go with each customer

  13. Each customer should have a purchase history

  14. Only authorized users can view customers

  15. The list of customers can be filtered by items purchased, date of purchase, name, phone-number, email or address


​

Now you have a lot more to go on, but your team doesn't think they can complete the whole thing in one, or even two sprints. They're worried about the size of the story and the number of unknowns. So you decide to break the story apart and focus on the essential functionality first.

Looking at the list of requirements, some areas of functionality start to emerge: create customers, retrieve customers, update customers, delete customers, validation, authorization, purchasing. You realize these are just CRUD operations with validation and authorization. In fact, this is a common pattern of functionality visible in many applications dealing with a collection of data.

The requirements fall under two features: Customers and Purchases. There are no solid requirements around purchasing. After discussing it with your client, it makes sense to tackle Customers first, and then delve deeper into Purchasing. For now, the Purchases feature will be deferred. We'll then use the velocity information we get from developing the Customers feature to help estimate the Purchases feature.

With this new insight, you start to break the requirements for Customers apart into user stories. Your goal is to create small stories which can be developed and tested during a single sprint. We want to minimize carryover.


Story 1: As a User, I need to view all Customers, so that I can manage contacts

  1. User can view existing customers

  2. User can view the first name, last name, image, address, email, and phone number of a customer


Story 2: As a User, I need to filter the Customers, so that I can locate those of interest

  1. While viewing the list of customers, a user can filter the list based on name, phone number, email, and address.


Story 3: As an Administrator, I need to create a customer, so that I can manually add a contact

  1. User can create a new customer

  2. User can enter the first name, last name, address, and phone number of a customer

  3. Only an Administrator can create a new customer

  4. User can enter Notes about the customer

  5. User can select an Image for the customer

  6. Phone numbers have to auto-format to (xxx) xxx-xxxx

  7. Zip codes have to be valid

  8. Changes to the Customer can either be Saved or Cancelled

Story 4: As an Administrator, I need to edit a customer, to keep information up to date

  1. User can edit an existing customer

  2. User can edit the first name, last name, address, and phone number of a customer

  3. Only an Administrator can edit a customer

  4. User can edit Notes about the customer

  5. User can view or change the Image for the customer

  6. Phone numbers have to auto-format to (xxx) xxx-xxxx

  7. Zip codes have to be valid

  8. Changes to the Customer can either be Saved or Cancelled


Story 5: As an Administrator, I need to delete a customer, to remove unused contacts

  1. User can edit delete existing customer

  2. Only an Administrator can delete a customer

  3. User is prompted to confirm the deletion


Now we have five small, well-defined user stories, where we started with a single gigantic one. If we wanted to further dissect our functionality, we could pull Validation our of stories 3 and 4, and turn that into a separate user story. After discussing this idea with your team, they think leaving validation in those stories is reasonable.

With your user stories properly fleshed out, you can stack-rank and estimate them. Since the functionality has been broken into smaller stories, each one is much easier to estimate. As a side-effect of dissecting the original user story, a number of unknowns were also clarified.

Let's take a look back at our original question of "what makes a good user story?" Naturally, there's no single answer to such a nebulous question. If you ask 10 Agile practitioners, you're likely to get 10 different opinions. However, there are some simple guidelines to keep in mind when creating a user story:

  1. Keep It Short​ – An ideal story can be developed and tested in a single sprint. Large stories lead to carryover and are hard to estimate.

  2. Keep It Relevant – Group related functionality in a meaningful way. Unrelated functionality belongs in different story.

  3. Keep It Essential – If it isn't essential to the spirit of the story, consider a separate story. Think minimalism.

These are just a few, among many, good considerations when creating your user stories. Writing user stories is a skill that improves with experience. I encourage you to continue learning and refining your practice.


I hope this has served as an enjoyable thought-exercise and spurred some interest in creating shorter user stories. If you have any guidelines of your own, or an interesting experience, please share in the comments.

Please note that I have intentionally been tool-agnostic, so the intent of this article is not lost on the presentation. I will explore available tools in future articles.

When an engineer makes a change to source code or tests, there are multiple steps before that change finally makes it into production. In the most basic form, these steps can merely consist of a developer compiling code on their development machine and copying the output to the production environment. Don't do this. Just don't.

This introduces innumerable opportunities for human error. In order to truly provide reliable deliveries, this process should be automated from end to end. To take it a step further, multiple stages of testing should be incorporated, along the way, to ensure the quality of the release.

Figure 1: Delivery Pipeline

To begin eliminating human error, some automated workflow needs to be put in place. This consists of a gated build, a continuous integration build, and one or more release definitions. Each build provides another layer of confidence in the quality of the delivery.

It all starts when a software engineer or quality engineer makes a change to source or test code. In order to ensure that the change passes basic inspection, we set up a gated build. The gated build is triggered automatically when the developer attempts to check in a change. It builds the code and executes the unit tests. Only if the code compiles and all unit tests pass, will the change actually be committed to source control.

Figure 2: Gated Build

This ensures the health of the code-base in two ways. First, the change actually compiles, thereby preventing blockers for other developers. It is very costly for development to halt, because somebody checked in something that doesn't compile. Second the unit tests ensure that each individual part of the code works as designed. This is the first layer of protection from costly regression errors.

Once the change hits source control, another process is set into motion. The change is retrieved from source control and built, similar to the gated build. This time, however, instead of running unit tests, the build executes functional, integration, and system tests.

Figure 3: Continuous Integration Build

Each type of testing provides an additional level of confidence in the final product. Functional testing verifies that the individual components behaves according to the requirements. Integration testing ensures that the components work together, and finally, system testing validates the entire system as a whole.

This type of build is known as a continuous integration build, because every change is automatically integrated into the system. Then it is tested against the complete system.

If any test fails along the way, then the entire build fails. It's only if all tests pass that the build artifacts get turned into a release. The entire process is depicted in the following flowchart.

Figure 4: Delivery Workflow

Each step along the way can be automated. For safety and accountability, it's a good idea to add some human control along the way. This is provided at two stops in the chain. The first is creating the release from the build artifacts. Just because you check something in doesn't mean you want to turn it into a release. So this part is left up to a human.

Second, after creating a release, it is up to the humans to decide what to do with it. In an ideal situation, there should be at least three release environments: quality assurance (QA), pre-production, and production. Once a release has been made, it can be deployed to any of these environments.

Figure 5: End-to-End Delivery Pipeline

The release would first be deployed to a QA environment, where it would be tested throughout development. When the change is ready to be hardened for an upcoming delivery, the same release can then be deployed to pre-production. Once the team and client are confident in the final quality of the release, it can be deployed to production.

Automating the delivery pipeline takes the guesswork out of providing quality releases. It frees the engineers to focus their time and energy where it matters, rather than on the overhead of integrating changes and running tests manually. If you want to take your process to the next level, automating your delivery pipeline is an investment that will pay for itself.


Do you have your own stories or ideas about automating the delivery pipeline? I'd love to hear from you in the comments!

It's with great excitement that I am finally able to introduce the world to Teos. This company has been my vision for a very long time. Now that I have accumulated years of experience and expertise, I want to share my passion for creating great software with you. Quality and Usability have always been the core tenets of my practice, and you will hear a lot about those topics from me.

Quality is what distinguishes exceptional software from the rest. I've been in this industry long enough to have seen many ways of creating software that work. I've also seen many that don't. I'm sure I've even been guilty of a few anti-patterns in my life.

However, I've also brought successful projects to market by championing test automation, continuous integration, continuous delivery, and adherence to Agile principles. In the upcoming articles in my blog, I plan to delve deeper into each of these topics, because they all contribute to a quality product.

Software usability essentially describes the quality of the human-computer interaction. Whether you're talking about a web site, mobile app, traditional desktop application, or one of today's IoT devices, at the forefront must be consideration on how the user will actually use the thing. This can include visual elements, audio, and workflow.

I tend to favor a minimalist approach that doesn't burden the user with unnecessary information. With all of the things biding for our attention, from devices to dogs, we tend to be overstimulated in today's society. This shouldn't extend to our interaction with computers or devices.

The user should be presented with what they need, in order to accomplish what they want to do. They shouldn't have to sort through a bunch of unwanted data to find what's relevant. Think about the early search engines, and which one ended up on top.

Look forward to discussions like this, and many more, to come in the weeks to follow. In the meantime, please take a look around the site and explore the services we offer. What can Teos and you accomplish together?