Apprenticeship Patterns Ch 1 and Ch 2-6 Introductions (Revised)

The book Apprenticeship Patterns by Dave Hoover and Adewale Oshineye begins with its first chapter which centers on the concept and nature of apprenticeship. In it, the authors compare and contrast the apprenticeships of medieval Europe with the software apprenticeships of today. The following five chapters, of which I have read the introductions of each so far, focuses on individual concepts and attributes important to software apprenticeships. Chapter two focuses on “emptying the cup” or how an apprentice should set aside their existing knowledge in order to fully open themselves up to the different approaches of their colleagues and teachers. Chapter three reminds to not be too discouraged of the achievements of your peers as they’re still learning like the rest of us. Chapter four also reminds to not become too complacent or conceited and instead find ways to improve your weaknesses. Chapter five follows that up by advising that an apprentice should learn how to learn since software development is composed of two primary activities: learning and communication. Chapter six finishes off with the point that even though we live in an age where anyone can access limitless information through the internet, books still have some knowledge you can’t find online.

I mostly agree with the points made in the book save for the one in chapter six and even then, it’s mostly with the wording. The way the authors described their point made it seem that physical books have value outside of the internet in the information they have. This is despite the fairly likely chance that many of these books, such as Apprenticeship Patterns, already exist online in some form or another. I’m assuming that the authors only had sources exclusive to the internet like blogposts and websites in mind when comparing them to books. Taking that point of view in mind, I can see where they’re coming from especially with how easy it is to find inaccurate or outright wrong information. I’d go even farther than the authors though and suggest that people check the validity of their sources since physical sources can lie like online sources, the only difference is that it’s easier to lie with the latter.

Outside of the point in chapter six, many of the topics and attitudes covered I feel are not only important for software apprenticeship but also for any skill that an individual decides to devote themselves to. Optimizing one’s learning skills, constantly learning, constantly improving one’s weaknesses, not getting discouraged by the accomplishments of one’s peers, and opening oneself to other viewpoints are all extremely important to cultivating a craft. That’s because these skills all contribute to developing oneself into a well-rounded person, which in turn allows for an individual to learn and improve more quickly.

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

Concrete Skills

Concrete skills are something I feel as though I have an abundance, and simultaneously, a lack of. I guess this depends on what kind of skills are being referenced. If data structures, algorithms, or Leetcode is in question, I have some confidence. Not only are these topics I enjoy, but I also have solid knowledge in these areas. When it comes to automating tasks, or something more applicable to my current capstone situation, such as getting a strong grip on Docker and how each part of the project can be integrated with it, I feel… less qualified. 

The problem is, I think I can get to the technical knowledge I have, but only via the technical knowledge I am lacking. These barriers become apparent when working on a large project like the capstone. I look at the backend components, and I feel solid, even with little JavaScript experience. But picking up Vue.js makes me feel like I’m swimming in circles. There’s no point in making a backend without a frontend to support it, and I know this, but I’m not happy to confront it as it means abandoning my comfort zone for some crazy new frontend world.

          The learning pattern on concrete skills puts some much-needed pressure on me. It points out that I can have all the knowledge of theory and all the ability to learn quickly in the world, but if I can’t put real technical skills on a resume, I’ll never make it past the first round of hiring interviews. Rather than trying to find ways around the difficulties I face in everyday software development life, I should highlight my weaknesses and mark them down as learning opportunities.

          There has been a plethora of times in my CS career at which I confront a problem I have been avoiding and the knowledge I gain suddenly seems to apply everywhere. For example, last semester I learned the state design pattern, and because it came with some confusion, I dropped it quickly enough. Now, as I tried to make a Markov chain simulation in Java for my Math Modeling independent study, I realized a state pattern was a perfect fit. It took a couple hours, but I got it down and it feels great not only to have learned and used something new, but to know I have the knowledge to use whenever I need it going forward.

          I think my first focus should be some more surface level skills. As the chapter points out, the question, “If we hire you today, what can you do on Monday morning that will benefit us?” is one of the most important questions of the interview. If my best answer is, “Try really hard to get up to speed,” I’ll be job hunting for a long, long time. My new goal is to collect the skills I don’t know or feel uncomfortable with that are more common and focus my spare time on them. It will make daily life as a developer easier and take me further in my career faster.

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

RefinementCodeReview: A Review

Go check out the original article here! It’s great!

In Martin Fowler’s blog post titled, “RefinementCodeReview” he emphasizes the need to rethink the frequency with which developers review code. He points out that pre-integration reviews and pull requests, while important, should not be vital to the development process in the literal sense of the word. Fowler highlights the etymological reason we have collectively acknowledged that software is accurately named; it is soft, and like all malleable mediums, should be worked through from end to end. Fowler seems to suggest that a shift in lexicon from architectural comparison to Erik Dörnenburg’s town planning one would pay dividends in inspiring more frequent refactoring of older code. While this seems obvious, it’s a powerful distinction; if we approach old code like a large stone monolith carved with divine intentionality rather than a living, revisable set of rules used to build and expand, then we are certainly adding unnecessary apprehension around the development process.

“As soon as I have an understanding about the code that wasn’t immediately apparent from reading it, I have the responsibility to (as Ward Cunningham so wonderfully said) take that understanding out of my head and put it into the code. That way the next reader won’t have to work so hard.”

Martin Fowler, 1/28/2021 @ https://martinfowler.com/bliki/RefinementCodeReview.html

I found this quote personally compelling but also particularly salient when Mr. Fowler addresses the dreaded, yet somehow inevitable, scenario where a high-threat vulnerability in the code is exploited. He calls these rare-high-impact concerns and yields that truly no amount of testing will ever eliminate their existence but the process of running continuous and vigorous testing can make accepting a certain amount of risk from older or inherited code much more palatable. While the author doesn’t mention this pattern by name, he implies that these good practitioners of efficacious refactoring, who are more knowledgeable of a code base, who are better still at creating self-testing code, who are better even yet at continuous integration would create a virtuous cycle of software development.

From the blog CS@Worcester – Cameron Boyle's Computer Science Blog by cboylecsblog and used with permission of the author. All other rights reserved by the author.

Breaking Out the White Belt (Disambiguation)

As someone who has been a caddy, industrial mechanic, butcher’s assistant, retail manager, letter carrier, web development intern, substitute teacher, and referee over the course of my life, it’s safe to say that I’m no stranger to breaking out the white belt. The chapter sets up the scenario wherein you’re a competent programmer with a narrower-than-desired field of knowledge and although your competency allows you to feel confident in your day-to-day operations, this coziness with your language or technology stack has limited your ability to wrestle with the novel in a meaningful way. The suggested solution is to embrace the unknown and throw away your preconceived notions about what it means to program or write software, actively avoiding the temptation to relate your previous world to the task at hand. The authors call this mindful approach to limiting context “maintaining a not knowing stance”, an ethos that I would argue is truly the heart of science and fundamental for discovering something new. The case here is that we (the readers) are software developers and the personal discovery is the new world of idioms, approaches, and paradigms that we will hopefully be able to synthesize and, upon achieving contextual competence, apply.

The pattern certainly confirms to me what I already know; being humble is an evergreen approach to learning, however the authors chart territory that I do not know in the chapter and that is the premise given at the outset where one hits a level of competence and plateaus there. I’ve not really been able to wrestle with any technology stack or programming language long enough where I feel competent or fluent to meaningfully contribute, let alone act as a guiding beacon for peers. While I may not be ready now to apply what I’ve learned in the pattern, if I imagined myself a competent C++ developer accustomed to the object-oriented programming paradigm, I would then make an attempt to learn a declarative paradigm, perhaps functional programming. Ultimately one’s next foray in software development will tend towards whatever is productive for their endeavors, occupational or personal and should likely reflect the adage of “picking the right tool for the job”.

From the blog CS@Worcester – Cameron Boyle's Computer Science Blog by cboylecsblog and used with permission of the author. All other rights reserved by the author.

Apprenticeship Patterns Blog Post #3

After completing my apprenticeship introduction blog post and two different patter reviews, I am excited to keep reviewing more. For the next pattern from the textbook that I have chosen to review, I chose the “concrete skills” pattern. The book describes a situation in which you are trying to work with a group or at a job in which you do not have a very strong background in yet. This is ofter one of the most inconvenient thing when looking for starter jobs. Most jobs want individuals who have a good background so they know you will be a good fit for the job. The book also supplies us with a great solution to this problem however. Basically, it states that you will have a better chance getting the job if you can prove that what you lack in background work, you make up for in your ability to learn quickly and work hard to learn new things on your free time as well. The more jobs and projects you can accomplish/work on, the better your portfolio and background becomes overtime. Eventually you will find it easier and easier to get where you want to get, and it all starts with your first several projects/jobs. This specific apprenticeship pattern resonated with me primarily because I personally do not have a great background yet and am trying to create a good one. The advice from this section was super powerful, and to be honest, this might be one of the most important concepts discussed in the entire textbook!

From the blog CS@Worcester – Tim Drevitch CS Blog by timdrevitch and used with permission of the author. All other rights reserved by the author.

differences and benefits between JUnit 4 to JUnit 5:

https://www.baeldung.com/junit-5-migration

According to this blog what I study for the Junit 4 and Junit5:

JUnit 5 is a powerful and flexible update to the JUnit framework, providing various improvements and new capabilities to organize and describe test cases and to help understand test results. Upgrade to JUnit 5 is quick and easy: Just update your project dependencies and start using the new functionality.

JUnit 4 bundles everything into a single JAR file.

JUnit 5 consists of three sub-projects, namely JUnit Platform, JUnit Jupiter, and JUnit Vintage.

1. JUnit platform

It defines TestEngine’s API for developing new testing frameworks that run on the platform.

2.JUnit Jupiter

It has all the new JUnit annotations and TestEngine implementations to run tests written with those annotations.

3.JUnit Vintage

Support for running tests written by JUnit 3 and JUnit 4 on the JUnit 5 platform.

But here are four strong reasons to start writing new test cases with JUnit 5:

JUnit 5 takes advantage of features from Java 8 or later, such as lambda functions, to make tests more powerful and easier to maintain.

JUnit 5 adds some very useful new capabilities for describing, organizing, and executing tests. For example, tests get better display names and can be organized hierarchically.

JUnit 5 is organized into multiple libraries, so import only the functionality you need into your project. With build systems like Maven and Gradle, it’s easy to include the right libraries.

JUnit 5 can use multiple extensions at the same time, something that JUnit 4 cannot do (you can only use one runner at a time). This means that you can easily combine Spring extensions with other extensions, such as your own custom extensions.

The JUnit 5 tests look pretty much the same as the JUnit 4 tests, but there are a few differences you should be aware of.

The import. JUnit 5 uses the new org.junit.jupiter package. . For example, org. Junit. Junit Test into org. Junit. Jupiter. API. Test.

Annotation. The @Test annotation no longer has arguments; each argument is moved to a function.

Assertions. JUnit Assertions 5 now in org. JUnit. Jupiter. API. Assertions. Most common assertions, such as assertEquals() and assertNotNull(), look the same as before, but with a few differences.

The hypothesis. Assumption has been moved to org. Junit. Jupiter. API. Assumptions.

In summary, JUnit 5’s tests are more powerful and easier to maintain. In addition, JUnit 5 offers many useful new features. Only the features you use will be imported, you can use multiple extensions, and you can even create your own custom extensions. Together with the new features, these changes provide a powerful and flexible update to the JUnit framework.

From the blog haorusong by Unknown and used with permission of the author. All other rights reserved by the author.

differences and benefits between JUnit 4 to JUnit 5:

https://www.baeldung.com/junit-5-migration

According to this blog what I study for the Junit 4 and Junit5:

JUnit 5 is a powerful and flexible update to the JUnit framework, providing various improvements and new capabilities to organize and describe test cases and to help understand test results. Upgrade to JUnit 5 is quick and easy: Just update your project dependencies and start using the new functionality.

JUnit 4 bundles everything into a single JAR file.

JUnit 5 consists of three sub-projects, namely JUnit Platform, JUnit Jupiter, and JUnit Vintage.

1. JUnit platform

It defines TestEngine’s API for developing new testing frameworks that run on the platform.

2.JUnit Jupiter

It has all the new JUnit annotations and TestEngine implementations to run tests written with those annotations.

3.JUnit Vintage

Support for running tests written by JUnit 3 and JUnit 4 on the JUnit 5 platform.

But here are four strong reasons to start writing new test cases with JUnit 5:

JUnit 5 takes advantage of features from Java 8 or later, such as lambda functions, to make tests more powerful and easier to maintain.

JUnit 5 adds some very useful new capabilities for describing, organizing, and executing tests. For example, tests get better display names and can be organized hierarchically.

JUnit 5 is organized into multiple libraries, so import only the functionality you need into your project. With build systems like Maven and Gradle, it’s easy to include the right libraries.

JUnit 5 can use multiple extensions at the same time, something that JUnit 4 cannot do (you can only use one runner at a time). This means that you can easily combine Spring extensions with other extensions, such as your own custom extensions.

The JUnit 5 tests look pretty much the same as the JUnit 4 tests, but there are a few differences you should be aware of.

The import. JUnit 5 uses the new org.junit.jupiter package. . For example, org. Junit. Junit Test into org. Junit. Jupiter. API. Test.

Annotation. The @Test annotation no longer has arguments; each argument is moved to a function.

Assertions. JUnit Assertions 5 now in org. JUnit. Jupiter. API. Assertions. Most common assertions, such as assertEquals() and assertNotNull(), look the same as before, but with a few differences.

The hypothesis. Assumption has been moved to org. Junit. Jupiter. API. Assumptions.

In summary, JUnit 5’s tests are more powerful and easier to maintain. In addition, JUnit 5 offers many useful new features. Only the features you use will be imported, you can use multiple extensions, and you can even create your own custom extensions. Together with the new features, these changes provide a powerful and flexible update to the JUnit framework.

From the blog haorusong by Unknown and used with permission of the author. All other rights reserved by the author.

Sweep The Floor

This post will be about the “Sweep The Floor” apprenticeship pattern from the book, Apprenticeship Patterns by Adewale Oshineye and Dave Hoover. This pattern is about finding your place on your team, contributing to the teams work to earn their trust and respect, and growing as a developer. The pattern suggests taking on the undesirable peripheral tasks when joining a new team/project. This will help you learn more about the project, development as a whole, and will keep you away from the core of the project. These tasks are often overlooked in education so this can help you fill in the gaps of education while working on something low risk. This does not mean lack in quality though. keep good quality, as bad quality on these portions of the project can become troublesome later on.

There are some problems with this pattern mentioned by the authors that I agree with. One is that you may become the guy who they use to do such dirty work, lacking in opportunity to work on more challenging tasks. Another problem is that you may become intimidated by anything that isn’t the easy yet boring work. Although you learn from this work, there becomes a point where you start to plateau from lack of challenge. The authors solution for these problems are to advocate for yourself and look for every opportunity where you can show them you are capable of contributing to higher tier work. Showing them enthusiasm and skill should make them realize that you are ready and capable to move on to more skillful tasks.

I found this useful because everyone has this starting point where they’re at their first job in a profession and need to gain the trust of their team members. Showing them that you are there to contribute can go a long way and nothing shows that better than when you do the tasks that no one wants to do. Although I already had an idea of this, the book really gave me a solid idea of what to expect to do at my first job as a developer and how to get my team to welcome me.

From the blog CS@Worcester – Austins CS Site by Austin Engel and used with permission of the author. All other rights reserved by the author.

differences and benefits between JUnit 4 to JUnit 5:

https://www.baeldung.com/junit-5-migration

According to this blog what I study for the Junit 4 and Junit5:

JUnit 5 is a powerful and flexible update to the JUnit framework, providing various improvements and new capabilities to organize and describe test cases and to help understand test results. Upgrade to JUnit 5 is quick and easy: Just update your project dependencies and start using the new functionality.

JUnit 4 bundles everything into a single JAR file.

JUnit 5 consists of three sub-projects, namely JUnit Platform, JUnit Jupiter, and JUnit Vintage.

1. JUnit platform

It defines TestEngine’s API for developing new testing frameworks that run on the platform.

2.JUnit Jupiter

It has all the new JUnit annotations and TestEngine implementations to run tests written with those annotations.

3.JUnit Vintage

Support for running tests written by JUnit 3 and JUnit 4 on the JUnit 5 platform.

But here are four strong reasons to start writing new test cases with JUnit 5:

JUnit 5 takes advantage of features from Java 8 or later, such as lambda functions, to make tests more powerful and easier to maintain.

JUnit 5 adds some very useful new capabilities for describing, organizing, and executing tests. For example, tests get better display names and can be organized hierarchically.

JUnit 5 is organized into multiple libraries, so import only the functionality you need into your project. With build systems like Maven and Gradle, it’s easy to include the right libraries.

JUnit 5 can use multiple extensions at the same time, something that JUnit 4 cannot do (you can only use one runner at a time). This means that you can easily combine Spring extensions with other extensions, such as your own custom extensions.

The JUnit 5 tests look pretty much the same as the JUnit 4 tests, but there are a few differences you should be aware of.

The import. JUnit 5 uses the new org.junit.jupiter package. . For example, org. Junit. Junit Test into org. Junit. Jupiter. API. Test.

Annotation. The @Test annotation no longer has arguments; each argument is moved to a function.

Assertions. JUnit Assertions 5 now in org. JUnit. Jupiter. API. Assertions. Most common assertions, such as assertEquals() and assertNotNull(), look the same as before, but with a few differences.

The hypothesis. Assumption has been moved to org. Junit. Jupiter. API. Assumptions.

In summary, JUnit 5’s tests are more powerful and easier to maintain. In addition, JUnit 5 offers many useful new features. Only the features you use will be imported, you can use multiple extensions, and you can even create your own custom extensions. Together with the new features, these changes provide a powerful and flexible update to the JUnit framework.

From the blog haorusong by and used with permission of the author. All other rights reserved by the author.

Unit Testing vs. Integration Testing

The basic idea of unit testing is that you are testing individual units of source code that you have written to see if there are any bugs. Usually the code is deterministic so there are set outputs. The idea of integration testing is to test how a group of modules in your application are working together including how external dependencies are working with the code. This usually involves testing something that is non-deterministic in the application.

Integration testing usually comes after unit testing and is the more expensive to maintain. While the developers will run the unit tests, integration tests are usually required to be ran by a test team. This is partly due to the difficulty in finding errors in integration tests as well as the time it takes.

Integration testing is black box testing which means you are testing the inputs and outputs of the interface. An example of an integration test would be checking the interface to see if you are brought to your profile home page when you enter your username and password. Unit testing is white box testing so you are writing test cases for certain functions to see if they perform correctly. An example of a unit test would be writing a JUnit test case to test the deposit() method and assert that when you make a deposit of $50 to your bank account object (with initial balance of $0) that your balance is now at $50.

The main takeaway is that integration testing tests the interface and how multiple modules work together while unit testing is testing the source code of one function. Unit tests are done in early development while integration tests are done after you have some sort of product complete.

Sources:

https://www.guru99.com/integration-testing.html#3

From the blog CS@Worcester – Austins CS Site by Austin Engel and used with permission of the author. All other rights reserved by the author.