[flaviocopes] The Programming Basics Course - Introduction to Software Engineering

Introduction to Software Engineering

With the 2 previous modules as a solid base, we can dive into some more advanced Software Engineering topics

What is software engineering

Programmers often use the term software engineer as a synonym to describe their profession.

It’s common and I’d say it’s almost equivalent these days.

Software engineering however describes a specific kind of engineering that I could say is parallel to the craft of programming.

You could be a great programmer and not use even one of the main practices grouped under the umbrella term “software engineering”:

  • testing
  • requirements analysis
  • software design

All those things are focused on creating a well defined path towards building reliable, correctly working, and high quality software in our industry.

I’ve been to an engineering school, and I have a degree in computer engineering, so I know how those topics are very highly praised in the field.

Knowing about all those things will make you a more well rounded developer, so let’s dive into each one of them.

I will expand on 3 topics in this module:

  • Software lifecycle
  • Requirements analysis
  • Testing

but I want to say that the topic is really, really, really vast.

Take those things as starting points.

Software lifecycle

Traditional software books described the process of writing software in this way: you gather the requirements, then you start developing the software, done (with more intermediate steps, but you get the point).

Software is not built from top to bottom.

Building software is an iterative process that involves the analysis of the requirements, designing the application, developing one part of the application, writing tests, refactoring, performance optimization, and so on.

Agile methodologies like Scrum have risen over time to help in this effort. Everyone has a different opinion on the usefulness of those methodologies, and my take is that any methodology is better than no methodology.

Every week and month, you will go through all those phases of working with software, back to the drawing board for a new feature, or to rewrite the software from the ground up to create a new major release.

Software is a living artifact, it’s just never “done”.

Requirement analysis

Software is an intangible artifact.

Like all artifacts, you can’t just start building software and expect the end result to be how you envision it, especially when working in a team. Everyone of your team members might have a different idea of what the application should do.

But also when working solo on your project, it’s easy to hit a stumbling block and forget about the big picture.

One way to have the clear goals in mind right from the start is by performing a careful requirement analysis . At the end of it you’ll have a clear frame within which you’ll be able to operate.

The first thing to realize is that there are many stakeholders in any application.

  • The users that will use the application in the end
  • The person that required this application to you
  • The team lead
  • The domain experts
  • The investors

The needs of each stakeholder might overlap, but in general you’ll have different needs assigned to each different stakeholder.

This should be the first phase of any software project, and it will involve a lot of conversations and discussion.

At the end you will write a document with all the data you need. I generally do this simply, in a plain text file with this information, for each of the stakeholders

  • their name and role
  • their goals and needs

When thinking about the end users , you should ask yourself some key questions:

  • Who should our app be for?
  • What is our ideal user?
  • Why should they use our app? What’s their end goal?
  • How can the app serve they best?

Also describe this information in the text file.

Any project has constraints . You need to factor them into your analysis, and find ways to workaround them, if needed.

Document those constrains too.

The next phase is what is generally called use cases .

Document all the use cases for your application. In a todo app, the main use cases could be

  • adding a todo
  • checking the list of things to do today
  • organizing the todo list for tomorrow
  • marking a todo as “done”

Describe them in detais in the document.

Many tools exist to help project managers to do this task. I prefer to keep things simple, but needs might differ and you might use advanced project tailored for the task.

If you have a product manager, it’s great to contribute to the process to gain as much insights to the project as you can.

As mentioned in the previous lesson, you don’t just gather the requirements and you are “done”. This is an ongoing and iterative process, especially on projects with a long time frame, like SAAS applications or desktop applications that might be used for 10 or 20 years by your customers.

Testing

Testing is one way to prevent bugs. Intercept bugs. Raise your awareness. It’s the best way to stop bugs from generate when you edit existing code.

Code with a high number of tests, covering a lot of the functionality, is said to be well tested. With a high coverage of tests.

Testing is also the best way to ensure a program is doing what you want. With a wide range of inputs, you can tell what’s the expected output and the testing suite will make sure this is what is happening. And alert you if not.

Modern programming involves running the suite of tests any time you push your modifications to an existing program, to make sure your changes are not causing any new bug.

Best practices want you to always create the tests for your new code, so that the entire codebase is always well tested.

Testing is also a QA measure. For open source projects, it’s essential to have a good amount of tests, to signal other programmers that you care about quality and the tests are the first thing many people run.

There are various kinds of tests, and all combined they aim to help you produce software that works as expected.

The simplest is called unit testing . Those tests are the most common, and they aim to test a single item in isolation. A function. A class. A package. Having a great suite of tests pass will mean it is guaranteed to work.

Integration testing is a second level, more focused on having your singular items, tested in isolation using unit testing, talk to each other. Or talk to a separate service or the network or the file system or anything external.

End to end testing is another kind of tests, aimed at guaranteeing you that the app is working, flowing correcly from start to finish. Backend, frontend, rendering… Tools exist to help you do so. For Web applications in particular, Cypress is a solid option.