Software quality and bugs within startups with Maximiliano Contieri from Avature Product Stories Software quality and bugs within startups with Maximiliano Contieri from Avature Play Episode Pause Episode Mute/Unmute Episode Rewind 10 Seconds 1x Fast Forward 30 seconds 00:00 / 00:34:45 Subscribe Share Apple Podcasts Stitcher Google Podcasts Spotify RSS Feed Share Link Embed Summary: Everybody knows and hates bugs in software. You can’t fully avoid them, yet every single one is one too many. What can you do to have fewer bugs in your software? Today’s guest is Maximiliano Contieri, engineering project manager at Avature and computer science teacher at the University of Buenos Aires. He talks about code quality within software development, lean development in startups, and how to handle bugs. Episode Highlights/Topics: Why is a bug called a bug? Insects get burned and make systems work the wrong way Two Professions and Passions: How he started in computer programming and teaching Academic vs. Pragmatic Professional: Push for perfection, quality, or lean development Quality Mindset: You can choose not to have some quality, but you cannot avoid it Functional Tests and Features: Never break all things that were working—unacceptable Technical Debt: Increases, works, fulfills functions but blocks software expansion Lead by Example: Clearly communicate level of code quality, culture, and expectations Resources/Links: Maximiliano Contieri Maximiliano Contieri on LinkedIn Trustshoring Read the transcript: [00:00] Victor: Everybody knows them. Everybody hates them, bugs in software. You can’t fully avoid them yet every single one is one too many. What can you do to have less bugs in your software? Today’s guest is Maximiliano Contieri. Engineering, project manager at Avature and computer science teacher at the University of Buenas Aires. He’s been writing about code quality within software development for a long time, and we’ll go over his take on bugs and lean development in startups. [00:43] Victor: Maxi, welcome to the show. [00:45] Maximiliano: Thank you very much for having me on this show. [00:47] Victor: Yeah, my pleasure. I stumbled across one of your articles and I really liked it a lot and I think this is what we’re going to be picking up on here a lot. First things first. Why is a bug called a bug? Why do we call these things that way? [01:03] Maximiliano: That’s a long history. The name bug was first documented, I think it was in the fifties when computers were big machinery and heating machinery and actually real bugs, insects used to enter the computer. And of course they burned in the [01:26 inaudible] and this make the [01:30 inaudible] work in a wrong way. So one of the printed cards, because they used printed cards and [01:38 inaudible] first documented that, oh, this is the program and this is a bug. And it was actually the real bug. The real insect was in the card. And this is why we call it today. I think it’s a mistake bugs, because bugs are things that enter our system and make a lot of noise, a lot of mistakes. [02:00] And this is actually not what is happening because actually our cloud computers and our PCs and desktops don’t have many holes for the bags to enter sometimes, but it’s not a common user. Actually what happens today is that the bug is not external agent, introduce random external insect, but something that we as computer and software engineer enter as mistakes we make. [02:26] Victor: Right. A lot has evolved since the fifties, not just bugs, but for sure everything else as well. Thank you for the introduction. And now maybe let’s learn more about yourself as well in the meantime. I’ve mentioned quickly what you do, but what was your background? How did you get into computer programming and especially also teaching? [02:50] Maximiliano: I have a background in computer science. I studied at the [02:53 inaudible] at the University Buenos Aires, here in Argentina. And since I have two, two paths to parallel paths, I work as a teacher, as the academic. That’s very good for somethings. And I started working full time at the industry. I have two jobs since then, and this is very good because we have different visions. The academic vision and the professional, more pragmatic vision of computer software and especially software engineer. [03:23] Our profession is a very special profession in which the academia now is behind the industry. And this is not happening on many professions, on many jobs, I think, where the academia and the science is breaking the knowledge and then goes the industry. We are at the same time. So at the academic, we learn or we teach our students how to make things good, better with quality. And at the, industry, we make the same things, but we have the deadlines. We have commitments, we have commercial opportunities. So we need to balance them. [04:00] And it’s very difficult to have both and to teach the students. We have career clients, we have customers, we have deadlines, you cannot do everything perfect. And on the other side, although we have deadlines and ETA’s, and I think we need to have quality. So I’m hanging on both sides. And it’s very funny. I think I’ve been doing this for 25 years. I never quit teaching and I never quit working as a professional on top level industry on many, many different work. The first 10 years of my career I worked for the financial industry. Then I had three startups where I met all of the sites of the equation of working as a software engineer, not just engineering. And then the last four years I’ve been working on a big company and pushing for quality in every aspect on the company. [05:00] Victor: Thank you. That’s very interesting actually. You have enterprise, startups, academia, that’s a very broad view of literally everything, but most interesting is this conflict that you’re mentioning between academia and the professional world. Professional is more pragmatic, academia is pushing for excellence. And I guess every single project has that conflict somewhere. And that is even more critical within startups because the budget factor and the time factor, both are just so much tighter. And that obviously creates this conflict of what do we even do? Do we push for quality? Do we make everything perfect or are we lean? And so when I look at an MVP versus scalable software, should I differentiate? Should I try to build one and the same? What are different approaches here [06:01] Maximiliano: Well, when you build an MVP, you take some licenses for granted. I build several MVPs and you don’t really care for the large problems now. But you need to have this on top of your mind. If you are going to have a pitch on your startup, and this will be my product, you are not. Right now concerning our performances, scalability, but this is something you need to mention, how are you planning to do so? You don’t need to work on the MVP, taking in consideration how it will work with a million users, but you need to be sure and talk to your investors on how you are going to do it and how you’re going to address it. And rewarding quality, MVP needs to have good enough quality, because if your demo fails, you’re going to have a big problem and you need to be sincere on what is your technical debt and your automation debt, and your quality debt for yourself. [07:03] So you have beat, you have customers, you have investors, you have money, what do you do now? You can extend your prototype, your body prototype, or say, okay, I have my prototype. I have validated use cases. I have something that someone is going to pay for it. So let’s cover it. Let’s make it quality and throw out the prototype and build real software. So I will not advise you if you’re making an MVP to have full coverage and quality and zero defect, you wouldn’t go that way because cost of opportunity, your competitor is not working that way and is not going there, but you need to have a certain mind on what will be your quality, because people are going to ask you, so how are you going to address it, instead of two people, you have a hundred million? Instead of a low balancing with one server for this demo, you’re going to have a thousand servers working together? [08:06 How are you going to address your fails, your problem, et cetera? So that will be in the DNA of your company. You need to show people quality is very important because if you are not doing that, if you don’t have DNA and just make features and pull and more features and more things and [08:26inaudible] you’re going [08:28 inaudible] at the time when you have more thing than you can manage, and when bug tend to grow expansion. So I think you have to be more pragmatic even on MVP because of the shorten of time, money, and everything. But you need to have the mindset. Quality is the mindset. [08:50] So you can choose not to have some quality, but you cannot avoid it. You need to be aware of that. That would be my advice having. I had three startups and we had MVPs and we had [09:04 inaudible] and we have funding and quality was there. So we are going to have this demo and everything. They asked me about quality I was ready to answer because quality was there. But of course, product was not 100 back free. No product was 100 back free, but I was aware that when they put the money and say, okay, let’s have two years to develop the product. Okay. Now quality come back because I cannot work without you. So you need to be more pragmatic I think. [09:34] Victor: That’s true. I guess the challenge here is to really understand what level of pragmatism and what level of quality, and especially what level of scalability is enough or the right approach just for my stage because that also depends. You can’t say generally that MVP doesn’t need to be scalable at all. It depends. Is it B2B software that’s being internally used by five people or is it consumer facing and it’s freemium and if we expect our, I don’t know, ad campaign on TV to go well then immediately, a lot of people will be using it, right? [10:13] Maximiliano: Yeah. Immediately. That’s the right word. [10:15] Victor: And I think that a lot of non-technical founders have an issue to understand like what’s good enough for me at this stage, right? [10:25] Advert: Hiring a perfect team isn’t a piece of cake, is it? To find a good candidate? You need to post a job on multiple job boards. Review like 100 CVS. Conduct at least a dozen initial interviews to make sure there’s at least a single specialist you would like to hire. But with superb hire by Trustshore, you can forget about all of the hiring headache. Find, meet, and hire skilled and dedicated assistance, ready to take over marketing, sales, administrative, customer support, data entry, or other tasks. Contribute to your business growth and help you reach your goals. Superb hire takes care of the entire recruitment process. You just have to show up for the final interview, visit Superbhire.com and book a free, no commitment call to learn more. It’s Superbhire.com. [11:11] Maximiliano: I’m another guy of TDD and TDD is great for adding a lot of exploratory functional issues because you will be on top of existing functionally that cannot break. You can develop software and break new things. That’s good. That’s acceptable, but you can never break all things that were working. That’s something that the user cannot accept. So if I ship you a new feature and the feature is not good enough. And it breaks you say, okay, you’re in beta testing, but why did you break that? That was working the last two years. And MVP is a layer on your layer of new functionality because you’re testing, you’re testing your prototype. So TDD is well set for that because you write layer one and just the code you need for layer one and it’s testing and it’s covered. And if you break it, you know it, and then you build on top of it, layer two and layer three and layer four. [12:04] And you’re pretty sure that layer one still works because it’s automated. So you cannot break it. And if you break it because your domain model is going that way, you are aware and say, oh, I broke it, but this is because, okay, I can take this decision, but the alarms and sound are sounding. And this is every process that works in a fast iterative and with feedback is very well fit. So I will advise TDD. You can build a prototype in TDD in minutes and add a lot of functionality in minutes, but you need discipline. You need never to go play something and say, I love it because I think, okay, you want to add it? So let’s get a user story on that feature you want to add, because unless you write the testing coverage, you cannot by definition of TDD build anything. [12:53] So if you say, Hey, partner, let’s check and this will be very good for the MVP. Well, let’s not add it. Let’s find a use case. Let’s automate the use case. Let’s write the test for the use case. Let’s see, we didn’t break the all use cases and then add it. And of course you [13:13 inaudible], you can go for your demo and say, feature one is working. Feature two is working. Everything is working and you can tell. And if you do that, you can rebuild your entire architecture for scaling your performance. You can change your database. You can do whatever you want because you have coverage. [13:33] And once you have coverage, you are good. Everything you do either works or does not work according to what you state. So I will advise. I’ll advise TDD for any everything. People who don’t know believe it slows down. But if I write this, this will be very slow and I need the MVP. It slows down at the beginning if you don’t know the technique, but once you master the technique, you can go even faster and with confidence because you don’t spend your time rewriting what you wrote because it didn’t break. So that would be an advice for startups. [14:11] Victor: And that makes a lot of sense. So for our listeners to quickly explain. So TDD, test driven development means before I write any code, I create the tests, automated tests actually, or maybe even manual. But mostly automated tests, which say, I don’t know, if the entire user journey, an eCommerce store from search to choosing a product, to putting it into your basket, to check out, and this has to work. And only then I create the documentation for how I’m implementing this. And then I develop it and then I already have a test. And I check it. And if it works or not, and then I have test coverage. [14:58] Maximiliano: Yeah, if you have the test coverage, you don’t even need the documentation because documentation is dead and tests are alive. You can ignore, a documentation is a contract. So if you break the contract, nobody will tell you. I think that when I go with the basket and paid in cryptocurrency, this will happen, but documentation is there, it’s a comment, it’s something. But if you write a test that’s leading documentation, you said, I will charge that using a blockchain. And the coverage says no, you’re breaking the use of fiat money, of banking money. Why did you do that? And you say, okay, this is not just documentation, but I use case I broke, so I need to fix it. So if I want to have the two features together, I need to have coverage for the two cases. And I need the code working for two cases. [15:46] So sorry for the documentation. But documentation activity do not work together well because we are accustomed to read test. And test our use cases, our functional test, something. They are not unit test in the traditional way, where you see a component, a class, a method, or something very low level. You can stay, you can have given them when and a user story. And saying, this is my test, given that I have a appointment in cryptocurrency when I buy this system and I do the checkout, then I have the fee and then goes, this is a functional test. And you cannot break it because if you break it, all the functional tests are going to say, oh, you cannot continue shipping this code because you broke it. [16:31] Fix the test, fix the coverage, and then move on. Sorry, I didn’t explain it, I assume many people is familiar, but sorry. And you were very correct to load that because I’m on TDD and I talk a lot of TDD, let’s define what TDD means. This is something you did. [16:51] Victor: Of course. Perfect. So thank you for that. And moving deeper into this and also into specific phrases. And in terms, speaking of this quality that we may be first in the MVP push a little bit down. So we also called doing that, taking on technical debt. Can you explain technical debt and what implications it has and how to pay it back? [17:21] Maximiliano: Technical debt is a dept. Nobody acknowledged this and the words, I don’t know who coined the term technical debt, but it’s pretty accurate. Why is it a dept? Because not only you have a debt on some amount of money, but the interest, the accurate interest of the debts are pushing you. So once you have technical debt, you start to have a lot of technical debt and technical debt increases. And this is something that like a real debt, your pay raises and the depth increases. Technical debt is something that is working. It fulfills the functional issues you have, but it is blocking you from expanding your software or improving your software on adding features. [18:06] So if you make, let’s go back to my example. You have a payment on a bank on a credit card, and then you have a payment on cryptocurrencies. And then you said, let’s have an info statement, a functional info statement. If I need to charge the credit card, I go this way. If I have to go, okay, but then you have another way of payment and you have a bunch of business rules together, and this is technical debt, because you no longer can expand your ifs, your conditions, to a point where you can easily add another method of pay of payment, because your system is not ready or is not generalizing. [18:49] So you can never do over generalizing. This is something that goes into the academia, where my student says, oh, I have a currency. And I will model every possible currency in miles and everything future. Now this is over generalization, over design. And this is a big problem. TDD do not allow you to make over generalization because you cannot write code. You have not a use case. So once you have 10 use cases of checking out your [19:17 inaudible], and this is working, this is good. But you say it’s increasingly difficult to add new currency. Everything. I need to add a lot of things. [19:29] So why don’t we find out what is going on and what have we common with charging someone for some product, and let’s not increase this debt. So because you have full coverage, you can do whatever you want with your code. Noticing you are not breaking your user stories, your existing user stories. So you say, I will address this technical debt. I will remove all this if then else functional. [19:56 inaudible]. And say, I will make a work, I will create a concept of a charge. And this will make the new one, the new payment method to enter in a open close principle, because you have your working model and you can easily add a contract on new things and you didn’t break it. [20:21] So what I told you was a kind of refactoring, a functional refactoring, but you can only do refactoring if you have coverage. Because if you refactor something that is not covered, you’re breaking things must probably. So this is a consequence. A technical debt need to be addresses when it hurts. And this is difficult to explain, how do I know? You know, because you are tracking, how long does it take you to make changes? And once the software is not easily change, you are losing opportunity. You’re losing against your competition because your competition are fast enough to make changes. [20:59] And either they are making new ifs and they will break and have a burnout very soon, or they have paid the debt and they can easily add new payments. And this is very good for estimates, because once you have generalized and pay your debt, adding new features is more easy and you don’t come into the crisis of, I’ll estimate 10 days, one it took two months because you have debt. So let’s address the depth and the depth is hurting. And this is the moment to address your depth. [21:29] Victor: Yeah. I find this very interesting. And also that explanation is that this is actually the interest, right? [21:37] Maximiliano: Yeah, that’s what is a debt, nobody understand it. This is a debt. This is not something you owe, you have a fixed amount. It’s not fixed. It’s increasing every time. That’s why it’s a debt. [21:50] Victor: The interest maybe increases the debt when you continue going down the hole, but you just pay it every single day. Because things take longer. They’re less estimatable. And this is the interest that you’re paying every single day when you have technical debt. You can just do simple, normal mathematics. You ask your developer, let’s say, even before you start your MVP, what does it take to do this? He’s shook, maybe let’s take a number, a hundred grand. And what does it take to make it fast, 50 grand maybe. Like you’re borrowing $50,000 against your own software, which probably means that going down the road, you will pay 10% more every month. [22:35] You pay the 10% interest, 5,000, for example, every month going down the road, because it is more complicated to do things until you pay it back, which might be even more complicated now than it was before. But the general concept really works. And that is almost fascinating. [22:52] Maximiliano: Yeah. But it’s not just about money. People tend to grow frustrated with a system with technical data. And nowadays it’s so difficult to get people excited and working with you. So if you’re working, everything is excited, let’s build, let’s build a different stage. But once you say I have a two year product, I have funding. I can pay you. And people come to you and say, let’s add this, but it has a lot of technical debt, but you’re not so sexy about that. And people is going to go to another MVP, another company or someplace, because nobody likes technical debt. And nobody likes other people technical debt. So it’s not just about money and cost of opportunity. It’s about confidence. And it’s about doing our work in a pleasure way. We have a software engineer, we have a lot of jobs. [23:44] We have a lot of work, and we are competing against a lot of people. And even sometime a company can pay you less, but you can work there in a continuous integration and agile way. And you can say, let’s go there and build a [23:59 inaudible, but I can pay you well, but I have technical debt. I need that 12 features. Well, I can work a couple of months, get a lot of money and go there where I feel more professional. And I think my work is better. So it’s not just about money. It’s about people. Some point it’s about people. So pay the debt always. [24:20] But not always. You need to be pragmatic because when you have a junior programmer and you say, let’s ship this feature, we have ITA. And we need a commitment to ship this for just in time in 10 days, and 5 days after, so I’m working on a framework to reduce technical. No, let’s be pragmatic. So you need to balance as always. And there are no [24:40 inaudible]. You need to know where it hurts. And you can say, I can push it because it wouldn’t be no [24:47 inaudible]. If you don’t need the money, you don’t have. It’s okay to have debts, but you need to be aware of what you’re paying. And this is why it’s a debt. [24:58] Victor: I think you cover two very interesting points here. So for one, is that we currently live in a world, in market situation, where maybe it makes no sense for you and your business to refactor or get rid of your debt. But you simply won’t find any programmer who wants to work on your software. And this is a real danger that we actually see every day and for that reason, and that reason alone, you will have to address this. And it might be very frustrating, but unfortunately, this is out of our control. [25:33] And the second thing that you said about clear communication and expectation setting. I think this is something that is lacking a lot in the industry of being clear about, we’re currently in this phase. This is how we want to build the software right now. It’s okay to take on technical debt. It’s not okay. What level of quality do we actually want to achieve? And so my question really here is how can I clearly communicate what level of quality to expect? How do I create that culture? [26:08] Maximiliano: Oh, tough question. Good question. I think you need to address by example. People will follow you if your decisions are coherent, are not contradictory. So if you say we don’t want bug, less quality. And then you say, push it, push it and fix it and take it and take it to production, you are making contradictory moves. So you need to be very concerned with every decision because people look after you when you take your decisions. So you need to be very clear on what are your goals and which is your quality level and stick to it. So people say, oh, I work and we have a backlog of bugs and bugs are [26:56 inaudible] and we don’t fix it because we have a custom of opportunity for shipping new feature. [27:02] But once a new bug enters and I say, oh, this will be a very, very difficult problem. And I want to address it now, we work together on this bug. That means why this, and not those, because this is going to have a very difficult problem? And this is over the threshold of what we can tolerate on clients. Why don’t you address all your bugs? Because that kind of balance are there. We push no bugs and people likes more of that feature because it adds value for their business and can tolerate the bugs. But you need to be very clear where the line is, and you need to talk to your team and the people working with you. And once you decide to fix the bug. I’m using the term bug. I hate the word bug, but I think the term everybody uses today. [27:55] But once you decide to fix the effect, you need to cover it, you need to make a [28:00 inaudible] automation test on that. You say, oh, this test is not working. Let’s make the call to fix this and don’t break the previous ones. And then you ship it and you can do it on Friday night and release to production on Friday night, because you have coverage. This is something that you can do once you have the confidence. If you are afraid of shipping on Friday night, you are not good enough on your quality. [28:29] Victor: I’m definitely afraid. I’m definitely afraid of shipping Friday night. That’s a can of worms that you open right there. Don’t ask your developers to ship on Friday night. But obviously, if you have that mature software development process, what in your mind is needed for mature software development process that just doesn’t produce bugs or minimizes the production of bugs. We mentioned TDD general test coverage. [29:00] Maximiliano: Yes. I told you that bugs should be, or defect should be there when you don’t foresee good side effects on somewhere you’re shipping good side effects. Because if you ship a new feature, it might be good enough coverage, and you ship it in the past other features and might good enough for coverage. And if you have integration use scenarios, the work, the two features work together. If you have a mature organization, your defects or your bugs will be unforeseen situations where good features interact together, or new players interact together. [29:38] And this is why your bugs shouldn’t be back by features, bug slash features. This work is okay. This also working, okay. They have coverage, but once they met together, they are not working very good. Why? This is all because you mix crypto with fiat and amount of currencies are not the same. And one has a lot of decimals and they were working very good themselves, but not together. So what is the defect or the bug, is trying to mix it, but did you foresee user wanted to mix in the wallet? No, this is something new that we can do in this. [30:19] Okay. Let’s fix it. But I have a problem because I have an if then else that, if I have five fiat money, and if I. Well, you have technical debt. Why don’t you model something that exists in the real world that is a mixer wallet. This is a concept that exist and you prevalent didn’t have, because you have technical debt. Let’s introduce this and let’s fix this. So once you have a mature process, you don’t find defects on existing features. You find defects on mixing together new features, new integrations, new products. [30:56] That is good. This is a sign that you are working. When the user change your system and use it in unexpected ways. And you need to expand and you expand it fast, because if the user twisted your systems and you need to work a year on, well, technical debt is very high. So that is a good indicator on how is your mature process. But if the user says, I want to have $1 and $2 and add them, and it’s not $3, oh, you didn’t cover it, the basic feature, that is an indication of a clear problem in the past. And this is automation there. This is worse. [31:36] So I’m not giving you strike rules, should be hinting due to experience, sorry. When you encounter things and you do root case analysis, you need to do root case analysis on why that defect happens in production. And if you have a good chain and a good process, you will have several components failing together. So about [31:59 inaudible] is just one component. For example, one bad programming thing works and gets into production. You have a very, very, very wrong problem on your process. [32:11] You need to have the coder making mistakes. The code reviewer, the QA, the automation process, the shipping, the testing, the deployment, the station. Everything must fail in order for you to have a bug in production if you are mature enough. And on MVP, you don’t need all them, but you need some of them. Let’s make a, a peer core review. Let’s make unautomated, let’s not ship it the day before to go into a demo for pitching for a million dollars. Let’s not do that. You cannot afford to pay all, I think all, all dimension, because this is a mature organization. And if you build that, you lose cost opportunity for MVP. Don’t ship that, but be ready for shipping it. [32:54] Victor: A hundred percent, be prepared and build mature software. Thank you so much. This has been insanely insightful and helpful, and I appreciate you being on there. Where can people find you to learn more about you? [33:09] Maximiliano: Well, I have a blog. I write at, at my own blog, which is my name it’s MaximilianoContieri.com. It sounds like Italian or Argentina. And I published two or three articles for today talking about software development, code mails, refactoring, TDD, software quality and other stuff. I’ve been writing a lot since the pandemic. We are no longer in the pandemic, but I keep writing. That’s something that I don’t do that for a living, but I wanted to conceal the, academic and the professional. And you can follow me there, or you can follow my Twitters too. It’s Mcesee1, but you can find it on the blog too. [33:55] Victor: Awesome. Highly recommend it. Thank you so much for joining us. [33:59] Maximiliano: Well, thank you. Have a nice day.