Author Archives: V

security testing

For this week’s Software Testing blog post, I wanted to have a glance into the world of security testing.

In a big picture sense, security testing is a simple concept to understand even from a layman perspective. It entails testing software for any vulnerabilities, risks or threats that can be posed and to any stakeholders in the software that could cause a negative impact. Stakeholders can include the company that creates and / or deploys the software, the end-user, and even the software itself.

There are many different types and methods to security testing, and in the blog post I would like to go through a couple that caught my mind, with information courtesy of Oliver Maradov’s very thorough security testing blog post on BrightSec.

Before getting into the actual methods, I found some key principles at the start of the article noteworthy to mention as well. Confidentiality and authorization have to do with limiting access to sensitive data, with authorization only allowing access on the basis of permission. Authentication is the principle of verifying identities that access data. Integrity and availability are crucial to preserving the consistency of data and making sure that is accessible when needed without failure. Lastly, non-repudiation sets a principle of of logging while further making sure data is accessible.

Now, for the first subject in the article that I found interesting. What first caught my eye was the use of the different ‘box’ testing methodologies, that is, black box, white box and grey box testing. The reason I was interested is because the application of black box testing makes a lot of sense (compared to the standard software development application, in my opinion) in a security context. Essentially, where black box testing for software developers mostly deals with the specifications prior to writing the code for the system, black box testing in a security context means approaching software that has been written through the prespective of an attacker. We typically see this through ethical hacking and penetration testing. I just found this a lot more compelling than the software engineer side of black box testing.

The second subject I found compelling was the section on DevSecOps. The idea of DevSecOps is to, as the name implies, merge the software development, security and operations process together to ensure the whole endeavor of creating a great piece of software is built from the ground up with good principles in a multi-faceted way, and to ensure that each team member has a level of understanding of the key principles. As such, the end product should (hopefully) become a product of a strong approach to each process.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

share your knowledge

As my final Apprenticeship Pattern blog post for my capstone course, I found it fitting to write about the “Share What You Learn” pattern. The idea is fairly simple, if you are gaining knowledge on a topic, you should be able to share that knowledge with others effectively to foster mutual growth, which results in everyone building on their ‘craftsmanship,’ which further results in better products from everyone involved.

We don’t work in a vacuum by ourselves, and so communication is incredibly important. We will always be working on teams of software developers, and even in our personal projects, we are working with information that we are informed about from the entirety of the software development ‘community.’ As such, learning to communicate your ideas and share your knowledge is always great for your team.

Different people have different specializations, and in software development, we have our own specializations and interests within this field, and it is beneficial to not only contribute your expertise to the project you are working on with your team, but also share things about that expertise to get everyone on the same board with what you are doing, and perhaps foster growth in them as people and the project as a whole.

The intersting thing is that you can also learn from others’ specializations and expertise when you are sharing your own, and you can also build on your knowledge from ideas and suggestions that others may make when hearing your ideas. It’s a bounce back and forth.

I think everyone has probably experienced this to some extent, even in small circumstances. As the authors mention, simply knowing one small thing more than another person allows you the opportunity to inform that person about your piece of knowledge, and that fosters growth, no matter how small. I know that, for me, I’ve had multiple people ask me about how to do things when they need reminders or help with assignments or issues that they run into at work, and in that situation, it is beneficial to know how to communicate solutions, suggestions and feedback in a way where everyone stands to gain.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

test-driven development

I’ve been working on a homework assignment where I’ve been tasked with undergoing the process of test-driven development while working on a code kata where I am to count the number of times each word in a string appears whilst ignoring special characters, spaces and new lines.

To summarize what test-driven development entails quickly, I consulted a blog post by Denis Peganov. Basically, when you do test-driven development, you write tests before you write the code. In practice, this means you have to figure out what the inputs and outputs should be for the code you’re working on, then organize the order with which you should be fulfilling tests in. Denis also mentions the cycle of test-driven development with the red, green and refactor phases. You start with a failing test in the red phase, write the minimum code to make the test pass in the green phase, then, as the name implies, refactor the program to enhance the program’s design if necessary. Denis goes further to make a great point that the iterative nature of test-driven development lends itself to modularity and can create a flow to the evolution of the codebase where this strategy is being applied.

I have to say, doing this in practice is fairly enjoyable up until the point where you have to rewrite everything. The flaw (while it is based upon the practitioner of this strategy of software development) is that if you ‘mess up’ the order of the tests, you can reach a point at which your design needs to change so drastically that you are effectively working backwards. This doesn’t necessarily mean that the strategy is bad, it’s moreso that it does require practice and experience in order to have a smooth development. It also requires the willpower to refactor massive chunks of code when you reach a critical refactor point, which for me it may just be that I’m rusty with regard to coding.

Regardless of this critique, test-driven development does seem to be the best of both worlds. Not only are you able to properly plan software from specifications, but you also get to actively see the results of your code while developing it. It seems incredibly efficient in comparison to other philosophies of software testing, and for me it’s honestly more engaging to write tests and write the code than just writing tests and reading the code that already exists or the specifications alone.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

sprint 2 retrospective

During the course of this sprint, I spent most of my time looking at the ReportingBackend repository to figure out what was going wrong with the testing suite. I also had assigned myself to configuring the pipeline specifically in ReportingAPI with the linters, but unfortunately was unable to complete this issue because the team responsible for actually adding the linters to the repository was not able to push their changes before the sprint ended. I continued to act as the scrum master for the team, taking an active approach to making sure everyone is doing work, getting credit for their work, and setting up meetings when necessary. I had to help out a bit with other team member’s issues as well, providing some guidance.

Verify the Testing Suite works: Investigate the testing suite and see if I can get it to work, or at least figure out the magnitude of the problem. I applied a couple of fixes (one of which was in the build.sh script that I had a separate 0 weight issue created for, as I had already found the bug and fix prior to the sprint starting.), but it seems like the issue transcends the testing suite and is moreso an issue with the build process with the server.

This sprint was pretty rough, if I’m being honest. For what we did well, our communication overall improved, and the team was better able to utilize GitLab for their work. I think that everything on GitLab was better organized and most of the issues had better descriptions on them than what we had last sprint, and the weight assigned to issues seemed fairly accurate all things considered, aside from the testing issue (which I did spend a lot of time on). We also did work with each other more than we did on the last sprint.

Most of the issues that were assigned to our team were rushed together during the last week of the sprint (from my perspective at least, there may have been some confusion with pushing to GitLab). As such, we weren’t able to get to all of the issues, and only got 14 weight out of the 24 weight assigned to our team fully merged in. I was offering support during the whole sprint, but it seemed like team members were not able to coordinate into a meeting at the same time for most of the sprint. I don’t really have a great reasoning for this, it seems like things weren’t being done until the time was very short to were we couldn’t get everything done, taking all of our other schoolwork into account.

Ultimately, I think for next sprint our team really just needs to work on spreading work out during the entire sprint rather than getting things done last minute. We should also work on coordination and being more present, as when anyone asked if we wanted to do a meeting, the team would all say they were available and no one would take the initiative to actually begin the meeting. Part of that is on me as scrum master, but ultimately we should be willing to meet without having everyone on board if we are working on specific issues.

I was able to spread out my work fairly well as an individual, but I can’t say the same for other team members, and so as scrum master I should be more active in making sure everyone is doing their work not just so the project moves forward, but so everyone gets the credit they need for the course.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

mocking review (and more)

A while ago, we used the Mockito framework in Java during an in-class activity. If I’m being honest, I wasn’t paying full attention to the material, and so I wanted to review some of the material in addition to looking into mocking more.

The idea with mocking is that unit testing without the actual classes being written is problematic solely because we can’t actually test stuff that isn’t written. This mostly applies to a specification-based testing environment, a subset of black-box testing. Mocking solves this by simulating the construction of objects and allowing set values to pass through for tests, which can then be refactored once the classes are actually created. As such, we can have tests created for the behaviors we want in our project, without having written the project yet, which is great if we’re applying specifications to tests.

This contrasts with stubs, pieces of code that are written as minimally as possible to get the test suite to function. Stubs are useful in that they can quickly provide the correct result for a test without the need of an outside resource, but what seems to happen is that as you write more tests, you end up writing the actual program in the process to make the tests match. This is good for test-driven development, where we actively write tests while we code the actual program, but if our interest is solely on writing the tests based on specifications, this isn’t a great approach.

According to a blog post by Rohit Khankhoje, mocks are great in that they are more cost-effective, acccessible and efficient than writing stubs or creating fakes. By setting up mocks, you have less set-up time for tests because you don’t need to have the system accessible in order to have a fully functioning test suite. While this is great, there are some obvious drawbacks. For example, tests that utilize mocking will still frequently have to adapt to new code changes when functionality is added to the project. This is more pressing with the idea in mind that tests will continue to pass with mocks despite code in the actual project changing, and so mocked tests need to be developed side-by-side with the actual code, otherwise the testing suite isn’t actually portraying accurate information regarding the accuracy and performance of the system.

As such, while mocking is a very strong tool, it seems to only be very useful in an environment where we don’t have access to code, and when we do have access to code (or we are also the coders ourselves, not just testers) it seems much more efficient to implement test-driven development.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

sweep the floor

When you first get placed on a team, it’s sometimes hard to get your bearings if you aren’t given an explicit task to work on to begin with. We sort of experienced this at the start of the semester, where we weren’t all too familiar with the Thea’s Pantry project even after working with forks of it for assignments in prior courses. Part of this is just the nature of working with something new, and having the expectation of providing value to it in a practical sense.

In this way, it makes sense the way we approached the issues that we took for the first sprint. For the most part, these issues were fairly simple and mostly plumbing, which can also be classified as sweeping the floor. The idea for sweeping the floor is that you take simple tasks that, while necessary, aren’t all that interesting, in order to build confidence in yourself with the project and build rapport with the team.

The authors make a good point in that it might not feel great to do as someone with a Computer Science degree that you worked hard for, but the reality is that the degree is really just a way to get your foot in the door. Same with any other way that you gained the qualifications to get accepted for a job or project that you’re working on. The real work is the work you do when you’re placed into a project, where you really get to apply the basics that you learned in college while also learning more practical skills.

I really think this is a good approach to take when you feel out of your element in a new environment. Maybe you just got hired for your first internship or even first full-time job, and while you are excited, you don’t really know how to actually provide value to the project, because you haven’t necessarily had that sort of experience before. This seems really helpful to get your bearings in a new project. The authors do mention a couple drawbacks to this approach, with the most notable one being the feeling of being stuck doing the small tasks without branching out due to anxiety, but there are ways out of this mindset too.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

sustainable motivations

I hear this a lot: getting into tech, and specifically software engineering, because of money. It certainly seems to be the case that many people since maybe the 2010s have worked on Computer Science degrees solely because of the income and luxury of it, rather than an actual enjoyment of it.

I always found myself good with technology. When I took my first Computer Science course in high school, I always ended up completing assignments in 10-15 minutes when the allotted time was around two class periods. This is what I’m good at, as far as I can tell, but that’s not necessarily enough for me to make a career off of. If I don’t care about it, then I’m stagnating. If my motivation is simply that I’m good at it, it doesn’t necessarily inspire growth.

These are two examples of unsustainable motivations. The idea is that we can get trapped in the motivations we set up for what we do, and they lock us into a (most of the time, negative) mindset. Instead of enjoying my day to day work, I’ll see it as just work, and want the day to be over as soon as it starts, without actually growing as a person or in my skill level.

While the solution given tries to offer a practical approach (writing down your motivations and how much they factor in to your decision to stay a software developer), I don’t necessarily think this is a strong solution. I’m inclined to say that you have to have a more inquisitive investigation to why you care about this career, and what is really motivating you. Ultimately, you yourself create this motivation, it’s not out there waiting to be found. You can either construct for yourself an enjoyment of the journey, or you can only care about the outcomes.

From this, I would say solely caring about outcomes is unhealthy, and that mindset lends itself to motivations like reputation and money. As such, you have to ultimately figure out how to care about the journey if you actually want to have some level of enjoyment in your career. Otherwise every day genuinely will be a soulless repetition of the last.

There’s a reason why Camus wrote that one must imagine Sisyphus happy. If Sisyphus were to redefine the pushing of that boulder as a journey, and the rolling down of that boulder as a satisfying conclusion and new beginning, then this punishment is not as severe. Of course, this requires a lot of mental effort, but I think it’s necessary to live a life that you can actually be happy with.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

sprint 1 retrospective

This sprint, I handled the Gitpod Dev Environment implementation for the Reporting System, specifically for the Reporting Integration, Reporting Backend and Reporting API repositories. I also acted as the scrum master for the team, handling most of the logistics and communication with the product manager.

Gitpod Dev Environments: Import extensions via the .gitpod.yml file, set workspace settings via the .vscode settings.json file.

In terms of what went well, we did complete most of the issue weight (75% of the weight assigned for the sprint was dealt with). Speaking with my team members, we agreed that the meetings were productive and efficient, and we didn’t waste time on any of the meetings we had. I made it a point to not have meetings that could have been done over a short text conversation, and it seems to have paid off. We also agreed that the communication that did occur was quality communication.

While we completed most of the work for this sprint, there was still 25% of the weight left. This was entirely comprised of the Reporting System Deployment issues where we had to write docker-compose files to set up MongoDB local volumes. In talking with the team, we thought that the weight didn’t reflect the difficulty of the task. In retrospect, looking at the Deployment epic again I can see that there was a lot of confusion, not only because of having to read through documentation for Docker, but also because the initial task that was to be done before the implementation through docker-compose files (the actual mounting of local volumes from MongoDB) was not accomplished by another team, and was even removed from their sprint. This was excacerbated by the approach we took, where each one of us worked on issues individually without much assistance from other group members. This changed towards the end when two team members worked on the deployment together, but by then it was still ineffective, especially considering the uneven distribution of issues. It seemed like the weight of issues did make sense in a vacuum, but considering that I did all of the Gitpod Dev Environment issues for example, it was obviously very quick to complete 4 weight when the first 2 weight was done, because it’s an application of what I just did.

Another consideration: I think having one person (me as the scrum master) deal with a lot of the issue-creating and handling GitLab logistics was efficient, it didn’t lend itself to the most clear working environment for my team members that weren’t very well acquianted with the workflow. Details were located in epics rather than easily accessed directly in the issue that was assigned, and it made it more difficult to see what you were actually working on. In addition, it made it seem as though I did all of the work in the activity log when in reality it was a cooperative process, and the byproduct is that I end up with all of the credit as well.

For next sprint, we should better assist each other as necessary on issues when complications arise. We should assign weights more accurately based on our experience on the last sprint, and allow all team members to share responsibilities on GitLab, both for learning and to better tell what’s going on. As an individual, I should be more proactive as scrum master to really address problems as soon as they arise, rather than leaving everyone to their own devices as long as they check in. With these adjustments, I think our team will be able to perform much better in the next sprint.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

spec based testing

As we move onto more code-based testing in class, I wanted to review some of the black box testing techniques we’ve gone over in class, especially since the most recent homework was somewhat confusing for me.

I’ll start off with boundary value testing. According to a blog post on SDET Unicorns, boundary value testing tests valid inputs in the domain (minimum, maximum, and one below and above them respectively), invalid inputs that are close to the domain, and any special inputs, such as empty strings or null pointers. This technique’s main use is testing boundaries, that is, it’s mostly concerned with whether or not invalid inputs are properly dealt with, and valid inputs are processed as valid. The drawback, as we discussed in class, is that it doesn’t really describe the different cases of valid inputs if there is branching taking place.

Equivalence class testing addresses this issue. From the same post above, equivalence class tests (or partitions, in the author’s words) divide inputs into, well, equivalence classes, or groups of input where behavior is expected to be the same. This also means that there are multiple groups of valid inputs, meaning this approach can effectively test different cases of valid inputs based on the specifications, rather than just testing if valid and invalid inputs behave as expected.

The reason why I wanted to look at these two specifically is because they are vital to understanding the decision table-based approach. I’m fairly confident in this approach because I found it fun to work with in class. It’s essentially a visualization and simplification of both boundary value and equivalence class testing, mostly equivalence class testing though, at least in my interpretation. The reason why I find it easier to work with decision tables is because they are much more efficient with regards to the space you use, even if the amount of mental work you have to do is larger.

It’s interesting because I found, in the homework at least, writing out test cases and the like for the non-table based approaches was somewhat frustrating because you have to consider each case even if they do the same thing, and write them out. With decision tables, you can optimize values into ‘dont cares,’ meaning that if the output is solely dependent on one of multiple inputs in this specific equivalence class, so you don’t have to care about what class the other values are. I really enjoy how this cleans up the entire process of black box testing. That being said, I understand that this can become very difficult to test as the complexity of a project increases.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.

retreat into competence

This is one of those patterns that I feels important to apply to everything in your life, honestly. It’s a well-known phenomena that the more you learn in a field, the more you know that you don’t know much. It’s a sort of complicated sentence, but it rings true: You realize the gaps in your knowledge the more you progress. I find it interesting to approach this problem by doing something you know well, but limiting yourself in doing that in order to not stay stuck and comfortable with what you know already. It makes sense as a solution in that you sort of look back and realize all the progress you’ve made, but don’t stay in that mindstate for too long because it will end in the stagnation of your learning.

I personally feel the imposter syndrome very strongly, not just in programming but also in music and other hobbies that I enjoy. I think this pattern would really help with those who, like me, have a tendency to notice the things we don’t know. The one thing is that I don’t necessarily think that this solution is a “one size fits all.”

I usually take breaks when I feel like this, or just brute force through it. The reason I do this is because, in all honesty, I don’t really like assigning myself work that doesn’t need to be done. It feels as though I’m repeating myself if I go back and do something that I already know how to do when it’s not even an important job. Granted, if I were allotted an opportunity where there is work that needs to be done with something I’m very comfortable with, I’m obviously ready and willing to do it, especially in that mindstate.

That being said, if I weren’t so stubborn about spending my time the way I do, I think this would be a great way to ease that sort of dread regarding the possibility that you don’t know very much despite all the time that you’ve spent. I think it’s definitely a good thing to look back at the work you’ve done and say “you know what, I have gotten better over time,” comparing past self to your current self feels a lot better and more productive than comparing yourself to others, because you can actually see where you’ve grown and what that you are, in some sense, competent.

From the blog CS@Worcester – V's CompSCi Blog by V and used with permission of the author. All other rights reserved by the author.