diff --git a/diagrams_source/README.txt b/diagrams_source/README.txt index 87ffbcd..1c3483c 100644 --- a/diagrams_source/README.txt +++ b/diagrams_source/README.txt @@ -12,11 +12,15 @@ Run using: -svgcleaner file.svg file_opt.svg +svgcleaner --multipass --coordinates-precision 3 --properties-precision 3 --transforms-precision 3 --paths-coordinates-precision 5 file.svg file_opt.svg -if you want the output in a human readable form rather than one massive line: +if you want the output in a human readable form so that it can be hand-tweaked, the best bet is xmlstarlet (svgcleaner can indent, but it doesn't always put line breaks where you need them): -svgcleaner --indent=1 file.svg file_opt.svg +cat file_opt.svg | xmlstarlet fo + +Once tweaked, you can use the following to strip the indentation: + +cat file_opt.svg | xmlstarlet fo -n | tr -d '\n' > final.svg Optimising PNG files: diff --git a/diagrams_source/lab02/calculator.puml b/diagrams_source/lab02/calculator.puml new file mode 100644 index 0000000..b975d2c --- /dev/null +++ b/diagrams_source/lab02/calculator.puml @@ -0,0 +1,26 @@ +@startuml +hide empty members + +skinparam { + Style StrictUML + ClassAttributeIconSize 0 + ClassStereotypeFont { + Size 12 + Style plain + } + DefaultFontName Roboto Condensed + Defaultfontsize 14 + Classfontsize 16 + Roundcorner 8 + Padding 2 + RankSep 100 + NodeSep 120 +} + +class Calculator { +-- + + add(x : Integer, y : Integer) : Integer + + multiply(x : Integer, y : Integer) : Integer +} + +@enduml diff --git a/diagrams_source/lab02/calculator.svg b/diagrams_source/lab02/calculator.svg new file mode 100644 index 0000000..91d223f --- /dev/null +++ b/diagrams_source/lab02/calculator.svg @@ -0,0 +1 @@ +Calculator+add(x : Integer, y : Integer) : Integer+multiply(x : Integer, y : Integer) : Integer diff --git a/diagrams_source/lab02/create-test-salt.puml b/diagrams_source/lab02/create-test-salt.puml new file mode 100644 index 0000000..ad9b487 --- /dev/null +++ b/diagrams_source/lab02/create-test-salt.puml @@ -0,0 +1,27 @@ +@startsalt +{ + { + Location: | ^Test Packages [java] ^ + Framework: | ^JUnit ^ + } + { +[ ] Integration Tests +. +{^ "Code Generation" + +{ +Method Access Levels | Generated Code +[X] Public | [X] Test Initializer +[X] Protected | [X] Test Finalizer +[X] Package Private | [ ] Test Class Initializer +. | [ ] Test Class Finalizer +. | [ ] Default Method Bodies +. | . +. | Generated Comments +. | [ ] Javadoc Comments +. | [ ] Source Code Hints +} +} +} +} +@endsalt diff --git a/diagrams_source/lab02/create-test-salt.svg b/diagrams_source/lab02/create-test-salt.svg new file mode 100644 index 0000000..5162e6e --- /dev/null +++ b/diagrams_source/lab02/create-test-salt.svg @@ -0,0 +1 @@ +Method Access LevelsGenerated CodePublicCode GenerationTest InitializerLocation:Source Code HintsGenerated CommentsJavadoc CommentsDefault Method BodiesTest Class FinalizerTest Class InitializerPackage PrivateTest FinalizerProtectedIntegration TestsJUnitFramework:Test Packages [java] \ No newline at end of file diff --git a/diagrams_source/lab02/domain_model.puml b/diagrams_source/lab02/domain_model.puml deleted file mode 100644 index f93aa05..0000000 --- a/diagrams_source/lab02/domain_model.puml +++ /dev/null @@ -1,59 +0,0 @@ -@startuml -hide empty members - -skinparam { - Style StrictUML - ClassAttributeIconSize 0 - ClassStereotypeFont { - Size 12 - Style plain - } - Defaultfontsize 14 - Classfontsize 16 - Roundcorner 8 - Padding 2 - RankSep 100 - NodeSep 120 -} - -class Customer { - - customerId : Integer <> <> - - username : String <> - - firstName : String - - surname : String - - password : String - - emailAddress : String - - shippingAddress : String - -- -} - -class Product { - - productId : String <> - - name : String - - description : String - - category : String - - listPrice : BigDecimal - - quantityInStock : BigDecimal - -- -} - -class Sale { - - saleId : Integer <> <> - - date : LocalDateTime - - status : String - -- - + getTotal() : BigDecimal - + addItem(saleItem : SaleItem) : void -} - -class SaleItem { - - quantityPurchased : BigDecimal - - salePrice : BigDecimal - -- - + getItemTotal() : BigDecimal -} - -Sale -up-> "**1..1**\r-customer " Customer -Sale -right-> "-items\r**0..*** " SaleItem -SaleItem -up-> "**1..1**\r-product " Product -@enduml diff --git a/diagrams_source/lab02/domain_model.svg b/diagrams_source/lab02/domain_model.svg deleted file mode 100644 index 9c2e859..0000000 --- a/diagrams_source/lab02/domain_model.svg +++ /dev/null @@ -1,76 +0,0 @@ -Customer-customerId : Integer «unique» «generated»-username : String «unique»-firstName : String-surname : String-password : String-emailAddress : String-shippingAddress : StringProduct-productId : String «unique»-name : String-description : String-category : String-listPrice : BigDecimal-quantityInStock : BigDecimalSale-saleId : Integer «unique» «generated»-date : LocalDateTime-status : String+getTotal() : BigDecimal+addItem(saleItem : SaleItem) : voidSaleItem-quantityPurchased : BigDecimal-salePrice : BigDecimal+getItemTotal() : BigDecimal1..1-customer-items0..*1..1-product \ No newline at end of file diff --git a/diagrams_source/lab02/domain_model_opt.svg b/diagrams_source/lab02/domain_model_opt.svg deleted file mode 100644 index 8be89d0..0000000 --- a/diagrams_source/lab02/domain_model_opt.svg +++ /dev/null @@ -1 +0,0 @@ -Customer-customerId : Integer «unique» «generated»-username : String «unique»-firstName : String-surname : String-password : String-emailAddress : String-shippingAddress : StringProduct-productId : String «unique»-name : String-description : String-category : String-listPrice : BigDecimal-quantityInStock : BigDecimalSale-saleId : Integer «unique» «generated»-date : LocalDateTime-status : String+getTotal() : BigDecimal+addItem(saleItem : SaleItem) : voidSaleItem-quantityPurchased : BigDecimal-salePrice : BigDecimal+getItemTotal() : BigDecimal1..1-customer-items0..*1..1-product \ No newline at end of file diff --git a/diagrams_source/lab02/invoice.puml b/diagrams_source/lab02/invoice.puml new file mode 100644 index 0000000..d6eab3f --- /dev/null +++ b/diagrams_source/lab02/invoice.puml @@ -0,0 +1,41 @@ +@startuml + +hide empty members + +skinparam { + Style StrictUML + ClassAttributeIconSize 0 + ClassStereotypeFont { + Size 12 + Style plain + } + DefaultFontName Roboto Condensed + Defaultfontsize 14 + Classfontsize 16 + Roundcorner 8 + Padding 2 + RankSep 100 + NodeSep 120 +} + +class "Invoice" as invoice { + - customerName : String + - customerAddress : String + - date : LocalDate +-- + +addItem(itemToAdd : InvoiceItem) : void + +removeItem(itemToRemove : InvoiceItem) : void + +getTotal() : Double +} + +class "InvoiceItem" as item { + - productName : String + - salePrice : Double + - quantityPurchased : Double +-- + + getItemTotal() : Double +} + +invoice -> "-items\r*" item + +@enduml diff --git a/diagrams_source/lab02/invoice.svg b/diagrams_source/lab02/invoice.svg new file mode 100644 index 0000000..743b556 --- /dev/null +++ b/diagrams_source/lab02/invoice.svg @@ -0,0 +1 @@ +-items*-customerName : String-customerAddress : String-date : LocalDate-productName : String-salePrice : Double-quantityPurchased : Double+getItemTotal() : Double+addItem(itemToAdd : InvoiceItem) : void+removeItem(itemToRemove : InvoiceItem) : void+getTotal() : DoubleInvoiceItemInvoice diff --git a/diagrams_source/lab02/main_menu_mockup.png b/diagrams_source/lab02/main_menu_mockup.png deleted file mode 100644 index 9b6c0fb..0000000 --- a/diagrams_source/lab02/main_menu_mockup.png +++ /dev/null Binary files differ diff --git a/diagrams_source/lab02/main_menu_mockup_opt.png b/diagrams_source/lab02/main_menu_mockup_opt.png deleted file mode 100644 index 0948dde..0000000 --- a/diagrams_source/lab02/main_menu_mockup_opt.png +++ /dev/null Binary files differ diff --git a/diagrams_source/lab02/merging_topic_branches.svg b/diagrams_source/lab02/merging_topic_branches.svg deleted file mode 100644 index 8d6774f..0000000 --- a/diagrams_source/lab02/merging_topic_branches.svg +++ /dev/null @@ -1,1505 +0,0 @@ - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - Team - - - Checkout master and pull to get team's recent changes - Step 1 - Currently checked out branch is indicated by a black border - - - - - - - - - - - - Topic - - - - - - Master - - - - - Topic - Start - We have an unmerged topic branch - - Checkout topic and merge master - Step 2 - - - - - Master - Merge - - - - - Team - - - - - Topic - - - - - - Master - - - - - Team - - - - - - - - - Topic - Result - - - - Step 3 - Checkout master and merge topic - - - - - Master - Team - - - - - - - - - - - Topic - Merge - - - - - - - - - - - - - - Master - - - - - - - Topic - Result - - - - - - - - - - - - - - - - - - - - Master - Delete merged topic - Step 4 - - Master - - diff --git a/diagrams_source/lab02/merging_topic_branches_opt.svg b/diagrams_source/lab02/merging_topic_branches_opt.svg deleted file mode 100644 index fbac361..0000000 --- a/diagrams_source/lab02/merging_topic_branches_opt.svg +++ /dev/null @@ -1 +0,0 @@ -TeamCheckout master and pull to get team's recent changesStep 1Currently checked out branch is indicated by a black borderTopicMasterTopicStartWe have an unmerged topic branch Checkout topic and merge masterStep 2MasterMergeTeamTopicMasterTeamTopicResultStep 3Checkout master and merge topicMasterTeamTopicMergeMasterTopicResultMasterDelete merged topicStep 4Master \ No newline at end of file diff --git a/diagrams_source/lab02/product_editor_dialog_mockup.png b/diagrams_source/lab02/product_editor_dialog_mockup.png deleted file mode 100644 index 31c7bad..0000000 --- a/diagrams_source/lab02/product_editor_dialog_mockup.png +++ /dev/null Binary files differ diff --git a/diagrams_source/lab02/product_editor_dialog_mockup_opt.png b/diagrams_source/lab02/product_editor_dialog_mockup_opt.png deleted file mode 100644 index c73190d..0000000 --- a/diagrams_source/lab02/product_editor_dialog_mockup_opt.png +++ /dev/null Binary files differ diff --git a/tiddlers/content/labs/lab02/_Labs_02_Add the .gitignore File.md b/tiddlers/content/labs/lab02/_Labs_02_Add the .gitignore File.md deleted file mode 100644 index a5f0d58..0000000 --- a/tiddlers/content/labs/lab02/_Labs_02_Add the .gitignore File.md +++ /dev/null @@ -1,14 +0,0 @@ -We added a task to a build script for creating the `.gitignore` file in last week's lab, but we didn't really discuss the purpose of the file. - -Many of the problems that we see students having with Git is caused by the student committing some build output or other rubbish such as Gradle caches to their repository. Build output and caches change very frequently which makes it easy for merge conflicts to occur if these files are part of your repository. Another common source of problems is the `DS_Store` files that Macs like to leave all over the place --- again because these files change frequently which can cause merge conflicts. - -The best way to prevent these problems is to keep the rubbish out of the repository in the first place. The way to do this in Git is via the `.gitignore` file. This file generally resides in the root of the repository or project folder (or both --- you can have many `.gitignore` files in a single repository). - -It can be a little bit tricky to create this file since pretty much all platforms hide 'dot' files (files that start with a '.') by default since they are generally considered to be system configuration files that users don't need to see most of the time. Windows Explorer outright refuses to create dot files, so you usually need to use the terminal. Macs have no way of creating files from the finder at all. - -This is why we added a Gradle task to the build script in last week's lab --- having a convenient way to create a `.gitignore` saves a lot of hassle. - - -1. Run the task now by selecting the root of the project in the Projects pane and then running the < createGitIgnore">> task via the Navigator pane. - -1. If you ever need to exclude anything else from your repository you can open the `.gitignore` file via the Files pane of NetBeans. Open the file now to take a quick look at it. diff --git a/tiddlers/content/labs/lab02/_Labs_02_Add the .gitignore File.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Add the .gitignore File.md.meta deleted file mode 100644 index 7351f0d..0000000 --- a/tiddlers/content/labs/lab02/_Labs_02_Add the .gitignore File.md.meta +++ /dev/null @@ -1,6 +0,0 @@ -created: 20200702091026430 -modified: 20200707005526287 -section: 2.3 -tags: lab lab02 incomplete -title: /Labs/02/Add the .gitignore File -type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md b/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md index 6fb6600..ea8d4ca 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md @@ -2,34 +2,32 @@ 1. Start NetBeans if you haven't already. -2. < Git > Clone">>. +2. Use < Git > Clone">> to clone the repository. - Once you have a Git repository open the <> menu item will move to the < Remote">> menu. + If you already have Git repository open the NetBeans the <> menu item be in the < Remote">> menu. - If asked for a master password at this point (or any later point), it is 'password' (without the speech marks). + If asked for a master password at this point (or any later point), it is: `password` -3. Switch to the GitBucket *quick setup* page in your web browser, and copy one of the *origin* URLs for your repository from the page. It will start with `https://` and end with `.git`. +3. Switch to the GitBucket *quick setup* page in your web browser and copy one of the *origin* URLs for your repository from the page. It will start with `https://` and end with `.git`. -4. Paste the URL into the <> box in NetBeans. +4. Delete the existing text in the <> text box in NetBeans. -5. Enter your GitBucket username and password and check the save password check box. +5. Paste the copied URL into the <> text box. -6. Under the <> section click <>. +6. Enter your GitBucket username and password and check the save password check box. + +7. Under the <> section click <>. Navigate to a location where you want to store your course project. If you have not done so already, you should create a folder named `info202` in the <> folder for storing your INFO 202 coursework. -7. Click <>. + Take note of this location --- you will need to navigate to this folder via the file manager soon. -8. Click <> again since there are no remote branches to worry about yet. +8. Click <>. - Make sure that the <> checkbox is checked. This will cause NetBeans to offer to create a project the repository after it is cloned. +9. Click <> again since there are no remote branches to worry about yet. -9. When NetBeans offers to create a project for you, check the <> checkbox so that we have the project added to the favorites pane, and click the <> button. +10. Change the <> to indicate that the folder is a git repository. We recommend that you append `_git` to the name, so the complete name would be `lab02_git`. - Choose < Java Application">> +11. Uncheck the <> checkbox. We will create the project ourselves via Gradle in the next section, so we don't want NetBeans to do this for us. -10. Name the project `info202_project` and delete the <> (leave it blank). - -11. Click Finish. - -You should see a project in the NetBeans projects pane that contains a class named `Main` in the default package. +12. Click <>. diff --git a/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md.meta index 1e08d62..4b6d2b5 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md.meta +++ b/tiddlers/content/labs/lab02/_Labs_02_Clone the lab02 Repository.md.meta @@ -1,6 +1,6 @@ created: 20200702091026430 modified: 20200707005526287 section: 2.1 -tags: lab lab02 incomplete +tags: lab lab02 title: /Labs/02/Clone the lab02 Repository type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md b/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md index 3bb4c45..4ffac3a 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md @@ -4,17 +4,17 @@ Select < Commit">>. - You will see a dialog appear showing you what files are going to be added to the repository. At this point it will just be the Gradle files, and the `Main` class. You should also see the `.gitignore` file being added to the repository --- this is a good thing since we want this file to be present on any computer that we clone the repository to. + You will see a dialog appear showing you what files are going to be added to the repository. At this point it will just be the Gradle build script and wrapper files. You should also see the `.gitignore` file being added to the repository --- this is a good thing since we want this file to be present on any computer that we clone the repository to. You will also see a text area in which you can add a *Commit Message*. You should always provide a useful message that describes what you have done since you last committed. - A Git commit message is a bit like an email message. The first line represents the subject and should very briefly name the feature/bug you were working on and what action you were performing on that feature/bug (adding, fixing, refactoring, completing, ...). There should be a blank line after the first line. The rest of the message can include a more detailed description of *why* the commit was added. Note the use of the word 'why' rather than 'what' in the previous sentence. We can easily see what changed --- Git has many features that can show us what changed so we don't need to repeat this in the commit message. The commit message is about describing why those changes were made. + A Git commit message is a bit like an email message. The first line represents the subject and should very briefly name the feature/bug you were working on and what action you were performing on that feature/bug (adding, fixing, refactoring, completing, ...). There should be a blank line after the first line. The rest of the message can include a more detailed description of *why* the commit was added. Note the use of the word 'why' rather than 'what' in the previous sentence. We can easily see what changed --- Git has many features that can show us what changed so we don't need to repeat this in the commit message. The commit message is about describing why those changes were made since that is information that will be useful to other developers (or yourself in 3 weeks once you have forgotten everything). In this case, we have just created the project, so your commit message should reflect that. Click <>. -1. You should see the Git log in the output pane. You will see a message at the end stating that the commit has finished. Since you are committing to the local repository in your home folder the commit should happen nearly instantly. +1. You should see the Git log in the output pane. You will see a message at the end stating that the commit has finished. Since you are committing to the local repository in your home folder the commit should happen nearly instantly (although the slow file servers can make 'instant' operations take quite a long time). 1. Open the repository browser using < Repository > Repository Browser">>. @@ -44,8 +44,6 @@ 1. Go back to the web browser and refresh the GitBucket repository page. You should now see that your repository has the NetBeans project in it. You will also see the commit message beside the files. -1. Explore the project by clicking the `info202_project` folder. Click the <> folder. You should see your `Main` class. - The general rules for committing and pushing are: * Commit after you have completed some kind of logical work unit. Examples could be: @@ -56,7 +54,7 @@ * You added a section to a documentation file. - * You completed some other milestone, such as finishing an important class, or completing an issue. + * You completed some other milestone, such as finishing an important class, or completing an issue that was assigned to you in the issue tracking system. One good way to think about logical work units is to think about the commit message that you would add when you complete the commit. If you can't think of anything to add that another developer working on the same project would find useful, then you might not be at a logical place to commit yet. diff --git a/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md.meta index be19732..7a22542 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md.meta +++ b/tiddlers/content/labs/lab02/_Labs_02_Commit and Push.md.meta @@ -1,6 +1,6 @@ created: 20200702091026430 modified: 20200707005526287 -section: 2.4 -tags: lab lab02 incomplete +section: 2.3 +tags: lab lab02 title: /Labs/02/Commit and Push type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Calculator Class.md b/tiddlers/content/labs/lab02/_Labs_02_Create the Calculator Class.md index 66fb1da..25fb7ba 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Create the Calculator Class.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Create the Calculator Class.md @@ -1,30 +1,13 @@ Create a new class named `Calculator` using < New File > Java > Java Class">>. -Add the following two methods to the file. This code should go inside the first set of curly brackets. +Add the following two methods to the class: ```java public Integer add(Integer x, Integer y) { - return x + y; + return x + y; } public Integer multiply(Integer x, Integer y) { - return x * y; + return x * y; } -``` - -The complete class should look like: - -```java -public class Calculator { - - public Integer add(Integer x, Integer y) { - return x + y; - } - - public Integer multiply(Integer x, Integer y) { - return x * y; - } - -} -``` -Your class may have a `package` declaration at the top --- that is fine --- leave it there. +``` \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Project.md b/tiddlers/content/labs/lab02/_Labs_02_Create the Project.md new file mode 100644 index 0000000..ef83bc5 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Create the Project.md @@ -0,0 +1,37 @@ +You should remember from last week's lab that we can create a project by adding a `build.gradle` file to a folder and opening that folder in NetBeans. This is our preferred way of creating projects since it means that we don't have to deal with the annoying multi-projects that we get if we use NetBeans to create the project. + +1. Locate the `lab02_git` folder that was created when you cloned the repository using the system file manager. + +2. Create a new file inside the `lab02_git` named `build.gradle`. You can create a new file by right clicking the background and using < Empty File">>. + +3. Copy the contents of <> into the file. This is the same `build.gradle` script that you saw last week, but with two additions: + + * The `repositories` section tells Gradle which repositories to use to download any library dependencies that are required. Maven central is the primary library repository for Java. + + * The `run` section tells Gradle to pass the `System.in` stream through to the application. By default Gradle does not do this which means that code that tries to read input from the console will not work. It is not often that we need to use the `System.in` stream, but if you are working on the Java review exercises then you will need to do this for a couple of the exercises. + +4. Save the file. + +5. Open the `lab02_git` folder in NetBeans using < Open Project">>. + +6. If you see a dialog appear that is warning you about problems with the project, just close it --- you can check the box on the dialog to prevent it from showing you this dialog in the future. The so called 'problem' is that the project needs a priming build. NetBeans will show a little warning icon over the project until the priming build is done. + +7. If you haven't done so already, build the project to fix the warning. + +8. Run the `createMissingSourceDirs` task by selecting the project in the projects pane and then double clicking the task in the navigator pane. + +9. Run the `createGitIgnore` task to add a `.gitignore` file to the repository. We only briefly discussed the `.gitignore` file in last week's lab. Any files or folders that are listed in this file will be ignored by Git. + + Many of the problems that we see students having with Git are caused by the student committing some build output or other rubbish such as Gradle caches to their repository. Build output and caches change very frequently which makes it easy for merge conflicts to occur if these files are part of your repository. Another common source of problems is the `DS_Store` files that Macs like to leave all over the place --- again because these files change frequently which can cause merge conflicts. + + We also have size limits on push operations on the GitBucket server. This is to stop students from accidentally pushing their entire home folder into a repository (it is surprisingly easy to accidentally create a repository in the root of your home folder). The limit is currently 20MB which is more than enough considering your total repository size at the end of the semester will generally be less than 1MB if you keep the rubbish out of it. + +
<> Since the file starts with a . it is considered to be a system file and will be hidden by default in most file managers. You can toggle the file manager setting to show hidden files (< h">> in the Linux lab), or you can use the files pane in NetBeans which does not hide these files.
+ + Open the `.gitignore` file in the files pane in NetBeans to take a look. As mentioned, this is a list of all of the files and folders that should be ignored by Git. + + When you commit, you are presented with a list of files that will be committed. It is always worth taking a quick look at the list to see if there is anything in the list that you don't want to be committed --- if so, cancel the commit and add the unwanted files to the `.gitignore` file. + +10. Run the `wrapper` task to add the Gradle wrapper to the project. + +11. If you don't see the four source directories in the project pane, restart NetBeans. As mentioned last week, this is a glitch that happens with NetBeans when the projects are stored on file servers or file systems that don't properly implement file change notifications. diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Project.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Create the Project.md.meta new file mode 100644 index 0000000..a239d5f --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Create the Project.md.meta @@ -0,0 +1,6 @@ +created: 20200702091026430 +modified: 20200707005526287 +section: 2.2 +tags: lab lab02 +title: /Labs/02/Create the Project +type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.md b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.md new file mode 100644 index 0000000..e891ba4 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.md @@ -0,0 +1,11 @@ +NetBeans can create the basic test class for us: + +1. Right click your `Calculator` class in the <> pane and select < Create/Update Tests">>. + +2. The default class name should be OK. Set the rest of the options as follows: + + {{/Labs/02/Diagrams/Create Tests Dialog}} + + These are fairly typical settings for creating test classes. + +3. Click <>. The test class will be created, and opened. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.md.meta new file mode 100644 index 0000000..dbf302c --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.md.meta @@ -0,0 +1,4 @@ +section: 3.3 +tags: lab02 lab +title: /Labs/02/Create the Test Class +type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.tid b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.tid deleted file mode 100644 index 1afe541..0000000 --- a/tiddlers/content/labs/lab02/_Labs_02_Create the Test Class.tid +++ /dev/null @@ -1,44 +0,0 @@ -section: 3.3 -tags: lab02 lab -title: /Labs/02/Create the Test Class -type: text/vnd.tiddlywiki - -NetBeans can create the basic test class for us: - -# Right click your `Calculator` class in the <> pane and select < Create/Update Tests">>. - -# The default class name should be OK. Set the rest of the options as follows:
-[[plantuml[ -@startsalt -{ - { - Location: | ^Test Packages [java] ^ - Framework: | ^JUnit ^ - } - { -[ ] Integration Tests -. -{^ "Code Generation" - -{ -Method Access Levels | Generated Code -[X] Public | [X] Test Initializer -[X] Protected | [X] Test Finalizer -[X] Package Private | [ ] Test Class Initializer -. | [ ] Test Class Finalizer -. | [ ] Default Method Bodies -. | . -. | Generated Comments -. | [ ] Javadoc Comments -. | [ ] Source Code Hints -} -} -} -} -@endsalt -]]] -
-These are fairly typical settings for creating test classes. -
- -# Click <>. The test class will be created, and opened. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Create the Test Object.md b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Object.md index 5031c80..4319233 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Create the Test Object.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Create the Test Object.md @@ -3,44 +3,16 @@ * Add a field to the class for the object. * Initialise that field in the `setUp` method. -We initalise via the `setUp` method since the `setUp` method will be run before each test method. This ensures that each test method will have a brand new object to test with and help to ensure that the tests are independent of each other. +We initialise via the `setUp` method since the `setUp` method will be run before each test method. This ensures that each test method will have a brand new object to test with and help to ensure that the tests are independent of each other. -Add the field. Fields go at the top of a class, just under the first curly bracket. The code is: +Add the field: ```java private Calculator calc; ``` -Initialise the field in the `setUp` method by adding the following code: +Initialise the field in the `setUp` method: ```java calc = new Calculator(); -``` - -The completed test class at this point should look like (ignoring any comments and `package` declarations): - -```java -public class CalculatorTest { - - private Calculator calc; - - @BeforeEach - public void setUp() { - calc = new Calculator(); - } - - @AfterEach - public void tearDown() { - } - - @Test - public void testAdd() { - } - - @Test - public void testMultiply() { - } - -} - ``` \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Calculator Class Diagram.svg b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Calculator Class Diagram.svg new file mode 100644 index 0000000..c497cbd --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Calculator Class Diagram.svg @@ -0,0 +1 @@ +Calculator+add(x : Integer, y : Integer) : Integer+multiply(x : Integer, y : Integer) : Integer \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Calculator Class Diagram.svg.meta b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Calculator Class Diagram.svg.meta new file mode 100644 index 0000000..b4ddfa7 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Calculator Class Diagram.svg.meta @@ -0,0 +1,3 @@ +tags: lab02 lab image +title: /Labs/02/Diagrams/Calculator Class Diagram +type: image/svg+xml \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Create Tests Dialog.svg b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Create Tests Dialog.svg new file mode 100644 index 0000000..5162e6e --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Create Tests Dialog.svg @@ -0,0 +1 @@ +Method Access LevelsGenerated CodePublicCode GenerationTest InitializerLocation:Source Code HintsGenerated CommentsJavadoc CommentsDefault Method BodiesTest Class FinalizerTest Class InitializerPackage PrivateTest FinalizerProtectedIntegration TestsJUnitFramework:Test Packages [java] \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Create Tests Dialog.svg.meta b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Create Tests Dialog.svg.meta new file mode 100644 index 0000000..b6a9402 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Create Tests Dialog.svg.meta @@ -0,0 +1,3 @@ +tags: lab02 lab image +title: /Labs/02/Diagrams/Create Tests Dialog +type: image/svg+xml \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Invoice Class Diagram.svg b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Invoice Class Diagram.svg new file mode 100644 index 0000000..743b556 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Invoice Class Diagram.svg @@ -0,0 +1 @@ +-items*-customerName : String-customerAddress : String-date : LocalDate-productName : String-salePrice : Double-quantityPurchased : Double+getItemTotal() : Double+addItem(itemToAdd : InvoiceItem) : void+removeItem(itemToRemove : InvoiceItem) : void+getTotal() : DoubleInvoiceItemInvoice diff --git a/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Invoice Class Diagram.svg.meta b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Invoice Class Diagram.svg.meta new file mode 100644 index 0000000..e22847c --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Diagrams_Invoice Class Diagram.svg.meta @@ -0,0 +1,3 @@ +tags: lab02 lab image +title: /Labs/02/Diagrams/Invoice Class Diagram +type: image/svg+xml \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_First Experiments.tid b/tiddlers/content/labs/lab02/_Labs_02_First Experiments.tid deleted file mode 100644 index 4f4185d..0000000 --- a/tiddlers/content/labs/lab02/_Labs_02_First Experiments.tid +++ /dev/null @@ -1,30 +0,0 @@ -section: 3 -tags: lab02 lab -title: /Labs/02/First Experiments -type: text/vnd.tiddlywiki - -Let's introduce the concept of automated testing using a very simple calculator class. It will have an `add` method and a `multiply` method, each of which takes two integer parameters and returns the integer result to the caller. - -The class diagram looks like: - -[[plantuml[ -@startuml -skinparam { - skinparam backgroundColor #ffffff77 - Style strictuml - RoundCorner 5 - Padding 2 - NodeSep 100 - Class { - AttributeIconSize 0 - FontSize 15 - } -} - -class Calculator { --- - + add(x : Integer, y : Integer) : Integer - + multiply(x : Integer, y : Integer) : Integer -} -@enduml -]]] \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_First Testing Experiments.tid b/tiddlers/content/labs/lab02/_Labs_02_First Testing Experiments.tid new file mode 100644 index 0000000..772b48c --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_First Testing Experiments.tid @@ -0,0 +1,10 @@ +section: 3 +tags: lab02 lab +title: /Labs/02/First Testing Experiments +type: text/vnd.tiddlywiki + +Let's introduce the concept of automated testing using a very simple `Calculator` class. It will have an `add` method and a `multiply` method, each of which takes two integer parameters and returns the integer result to the caller. + +The class diagram looks like: + +{{/Labs/02/Diagrams/Calculator Class Diagram}} \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Git and NetBeans.md b/tiddlers/content/labs/lab02/_Labs_02_Git and NetBeans.md deleted file mode 100644 index ff593d6..0000000 --- a/tiddlers/content/labs/lab02/_Labs_02_Git and NetBeans.md +++ /dev/null @@ -1,9 +0,0 @@ -You can commit and push from NetBeans by right clicking the root of the project. - -Commit using < Commit'>>. - -Push using < Remote > Push to Upstream'>>. - -If you are asked for a //master// password it is: `password` (which is the default master password in NetBeans). - -You will also be asked for your GitBucket username and password. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Git and NetBeans.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Git and NetBeans.md.meta deleted file mode 100644 index 958a419..0000000 --- a/tiddlers/content/labs/lab02/_Labs_02_Git and NetBeans.md.meta +++ /dev/null @@ -1,4 +0,0 @@ -section: 6 -tags: lab02 lab -title: /Labs/02/Git and NetBeans -type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Initial Set-Up.md b/tiddlers/content/labs/lab02/_Labs_02_Initial Set-Up.md index 86fbe4a..a0c8802 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Initial Set-Up.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Initial Set-Up.md @@ -1,44 +1,43 @@ -1. Create a new folder in your labs repository for this lab. +We need to add some bits and pieces to the `build.gradle` file to add support for unit testing to the project. You can find the file in NetBeans under the <> folder in the projects pane. -1. Start NetBeans. In the Linux desktop, you can find it under the <> menu. - -1. Create a new Gradle project in NetBeans using < New Project > Java with Gradle > Java Class Library">>. Make sure that the project is stored inside the folder you created in the previous step (look at the project location field). - - Name the project `lab02`. You can leave the other fields at their current values, and click <> - -1. Open the `build.gradle` file located in the project under <>. NetBeans generates build files using an outdated syntax. Also note that NetBeans defaults to using the older JUnit 4. - -1. We have some things to fix in the build file, so delete everything in that file and replace it with the following code:
+1. Add the `jacoco` plugin to the `plugins` section. The complete section should look like: ```java plugins { - id 'java' - id 'jacoco' - } - - repositories { - jcenter() - mavenCentral() - } - - dependencies { - def junitVer = '5.7.1' - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitVer - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVer - testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '2.2' - } - - test { - useJUnitPlatform() + id "application"; + id "jacoco"; } ``` - There are three frameworks being used here: + We will explain what JaCoCo is in a later section. - * JUnit 5 - * Hamcrest - * JaCoCo +2. Add the testing library dependencies to the project. The following section should be added to the bottom of the build script: - We will explain what each of these frameworks is doing as we go. + ```java + dependencies { + def junitVer = "5.8.2"; + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitVer; + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVer; + testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '2.2'; + } + ``` -1. You may get some warnings in your project at this point. This is because your project is using libraries that Gradle has not yet downloaded. Build the project using < Build Project">> --- this will force Gradle to download everything it needs and should fix any problems. + There are three frameworks being used here: + + * JUnit 5 (also known as Jupiter) + * Hamcrest + * JaCoCo + + We will explain what each of these frameworks is doing as we go. + +3. Add the `test` section to the bottom of the build script to tell Gradle which testing framework to use when running automated tests: + + ```java + test { + useJUnitPlatform(); + } + ``` + +4. Save the file. + +5. You may get some warnings in your project at this point. This is because your project is using libraries that Gradle has not yet downloaded. Build the project using < Build Project">> --- this will force Gradle to download everything it needs and should fix any problems. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Invoice.md b/tiddlers/content/labs/lab02/_Labs_02_Invoice.md index d1799ab..734786a 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Invoice.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Invoice.md @@ -1,61 +1,21 @@ -Now we need the Invoice class. Create a new class named `Invoice`. +Now we need the `Invoice` class. -To save some time we will just give you the completed version of this class. If your class has a `package` declaration at the top of the file then delete everything except the package declaration. Otherwise, replace your entire class with the following: +1. Create a new class named `Invoice`. -```java -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collection; +2. Add the four fields for this class to the class. If you are wondering where the fourth field is coming from, you have forgotten that association relationships are also fields --- there is a field for the `items` association that is a collection. -public class Invoice { +3. Add getters and setters. - private String customerName; - private String customerAddress; - private LocalDate date; +4. Add the `addItem` and `removeItem` methods --- they should add/remove the passed `InvoiceItem` parameter to/from the `items` collection. - private Collection items = new ArrayList<>(); + Don't forget to initialise the `items` field unless you enjoy debugging null-pointer exceptions. You should remember from INFO201 that `HashSet` should be your default collection rather than `ArrayList`. - public String getCustomerAddress() { - return customerAddress; - } +5. Add the `getTotal` method --- it should return the sum of all of the item totals for the items in the `items` collection. - public void setCustomerAddress(String customerAddress) { - this.customerAddress = customerAddress; - } + You can do this quickly using the following code: - public String getCustomerName() { - return customerName; - } + ```java + return items.stream().mapToDouble(item -> item.getItemTotal()).sum(); + ``` - public void setCustomerName(String customerName) { - this.customerName = customerName; - } - - public LocalDate getDate() { - return date; - } - - public void setDate(LocalDate date) { - this.date = date; - } - - public Collection getItems() { - return items; - } - - public void addItem(InvoiceItem itemToAdd) { - items.add(itemToAdd); - } - - public void removeItem(InvoiceItem itemToAdd) { - items.remove(itemToAdd); - } - - public Double getTotal() { - return items.stream().mapToDouble(item -> item.getItemTotal()).sum(); - } - -} - -``` -We got a little bit fancy with the `getTotal` method and used a lambda expression to iterate through all of the items, calling the `getItemTotal` on each, and summing the result to get the invoice total. We could have done this with a loop, but learning new techniques is how we gain experience. \ No newline at end of file + This is using a combination of lambda expressions and sequence streams (both of which have been in Java since Java 8) to iterate through all of the items, calling the `getItemTotal` on each, and summing the result to get the invoice total. We could have done this with a loop, but learning new techniques is how we gain experience. The old adage that Java is a verbose language hasn't been true for close to a decade. diff --git a/tiddlers/content/labs/lab02/_Labs_02_InvoiceItem.md b/tiddlers/content/labs/lab02/_Labs_02_InvoiceItem.md index 135feb1..1147995 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_InvoiceItem.md +++ b/tiddlers/content/labs/lab02/_Labs_02_InvoiceItem.md @@ -1,72 +1,9 @@ -Create a new Java class in your NetBeans project named `InvoiceItem`. +1. Create a new Java class in your NetBeans project named `InvoiceItem`. -Add the following three fields to the class. This code should go between the first set of curly brackets. + Add the three fields from the class diagram to the class. -```java -private String productName; -private Double salePrice; -private Double quantityPurchased; -``` +1. Generate getters and setters for the fields using < Insert Code > Getter and Setter">>. Select all three fields and click <>. Note that the insert code feature is context sensitive --- you need to have the cursor inside the class, between the two curly brackets or you will not see the <> option. -The result should look like this (ignoring comments and `package` declarations): +1. Add the `getItemTotal` method. It should multiply the `salePrice` with the `quantityPurchased` and return the result. -```java -public class InvoiceItem { - - private String productName; - private Double salePrice; - private Double quantityPurchased; - -} -``` - -Generate getters and setters for the fields using < Insert Code > Getter and Setter">>. Select all three fields and click <>. Note that the insert code feature is context sensitive --- you need to have the cursor inside the class, between the two curly brackets or you will not see the <> option. - -Now we need to add another method that will return the line total. Add the following method: - -```java -public Double getItemTotal() { - return salePrice * quantityPurchased; -} -``` -If your code is looking a bit messy then format it using < Format">>. - -The completed class at this point should look like (ignoring comments and `package` declarations): - -```java -public class InvoiceItem { - - private String productName; - private Double salePrice; - private Double quantityPurchased; - - public String getProductName() { - return productName; - } - - public void setProductName(String productName) { - this.productName = productName; - } - - public Double getQuantityPurchased() { - return quantityPurchased; - } - - public void setQuantityPurchased(Double quantityPurchased) { - this.quantityPurchased = quantityPurchased; - } - - public Double getSalePrice() { - return salePrice; - } - - public void setSalePrice(Double salePrice) { - this.salePrice = salePrice; - } - - public Double getItemTotal() { - return salePrice * quantityPurchased; - } - -} -``` \ No newline at end of file +1. If your code is looking a bit messy then format it using < Format">>. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Make the Tests Fail.md b/tiddlers/content/labs/lab02/_Labs_02_Make the Tests Fail.md index 58b14d5..30c863f 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Make the Tests Fail.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Make the Tests Fail.md @@ -2,23 +2,12 @@ You will see a pop-up window in the lower right corner of NetBeans that tells you that two tests were run successfully. That message box has an <> link in it --- click the link. If the dialog vanishes before you can click the link, you can open the test results pane using < IDE Tools > Test Results">>. -You will see the test results pane that tells you that all tests passed. That is not ideal since we haven't implemented them yet. It is a convention that we explicitly make all tests fail to remind us to come back to implement them. Add the following line of code to both methods to cause the tests to fail: +You will see the test results pane that tells you that all tests passed. That is not ideal since we haven't implemented them yet. It is a convention that we explicitly make all tests fail to remind us to come back to implement them. Add the following line of code to both test methods to cause the tests to fail: ```java -fail(); +fail("not implemented yet"); ``` -The following is what the `testAdd` method should look like once you have done this: - -```java -@Test -public void testAdd() { - fail(); -} -``` - -The `testMultiply` method will look similar. - You may need to import the `fail` method if NetBeans is complaining about it (via red squiggly lines under the method name). Use < Fix Imports">> to do this. Run the tests again. You should see that they now fail. This is what we want --- we will remember to come back and add the real testing code now since the tests will keep failing until we complete them. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Push to GitBucket.md b/tiddlers/content/labs/lab02/_Labs_02_Push to GitBucket.md new file mode 100644 index 0000000..8f64aa5 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Push to GitBucket.md @@ -0,0 +1 @@ +Commit your work and push it to GitBucket. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Push to GitBucket.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Push to GitBucket.md.meta new file mode 100644 index 0000000..fe337a5 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Push to GitBucket.md.meta @@ -0,0 +1,4 @@ +section: 6 +tags: lab02 lab +title: /Labs/02/Push to GitBucket +type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Review Exercises.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Review Exercises.md.meta index d0abbe4..4af3526 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Review Exercises.md.meta +++ b/tiddlers/content/labs/lab02/_Labs_02_Review Exercises.md.meta @@ -1,6 +1,6 @@ created: 20200702091026430 modified: 20200707005526287 -section: 7 +section: 8 tags: lab02 lab title: /Labs/02/Review Exercises type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Summary.md b/tiddlers/content/labs/lab02/_Labs_02_Summary.md new file mode 100644 index 0000000..8b5b6e9 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Summary.md @@ -0,0 +1,13 @@ +What we are aiming for when we are creating tests is to have something that we can rely on to catch the mistakes that we will inevitably make. + +This means that we need: + +* Sufficient tests. All important classes should be tested. Classes that aren't tested are classes that could contain bugs. + + Test your code as your add it. Waiting until you have completed a feature or module before testing it is not the correct way to work. If you add a method to a class, then don't consider that method to be complete until you have also added a test that tests that method. You don't want to be in the situation where you finally get around to adding the tests, and then discover that they all fail because you have bugs in a bunch of different methods that you wrote a week ago. + +* Comprehensive tests. The more comprehensive the tests are, the more that we can rely on them to catch our mistakes. + +* Tests that run quickly. We want to be able to test our code any time we make a change --- that way if a test fails, we know exactly what we did to cause that test to fail. If the tests take a long time to complete then we will only run them once or twice a day which increases the amount of changes that have to be checked to determine which one caused a test to fail. + +* Tests that work without needing manual configuration changes. If we have to fiddle with something to put the system into "test mode" then we are not going to run the tests as often as we should. The test code itself should configure the system for testing --- we should not need to modify any code or configuration files before running the tests. We will show you how to do this in the next lab, and lab 10. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Summary.md.meta b/tiddlers/content/labs/lab02/_Labs_02_Summary.md.meta new file mode 100644 index 0000000..6553b96 --- /dev/null +++ b/tiddlers/content/labs/lab02/_Labs_02_Summary.md.meta @@ -0,0 +1,6 @@ +created: 20200702091026430 +modified: 20200707005526287 +section: 7 +tags: lab02 lab +title: /Labs/02/Summary +type: text/x-markdown \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Test Classes.md b/tiddlers/content/labs/lab02/_Labs_02_Test Classes.md index 6f35cb6..51a4fa8 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Test Classes.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Test Classes.md @@ -1,51 +1,5 @@ -Generate test classes as you did in [section 2.3](#/Labs/Lab%2009/Create%20the%20test%20class). You will need to do this for both domain classes. +1. Generate test classes as you did in section <>. You will need to do this for both domain classes. -NetBeans will generate test methods for all of the public methods in the domain classes including the simple getter/setter methods. It is pretty much a waste of time to test the getter/setter methods. We are only really interested in the four methods that appear in the [class diagram](#/Labs/Lab%2009/Diagrams/Invoice%20Class%20Diagram). +1. NetBeans will generate test methods for all of the public methods in the domain classes including the simple getter/setter methods. It is pretty much a waste of time to test the getter/setter methods. We are only really interested in the four methods that appear in the <>. -Delete the test methods that are not related to the methods in the class diagram. You can also delete the constructors. - -The resulting test classes should look like (ignoring comments, and `package` and `import` declarations): - -```java -public class InvoiceTest { - - @BeforeEach - public void setUp() { - } - - @AfterEach - public void tearDown() { - } - - @Test - public void testAddItem() { - } - - @Test - public void testRemoveItem() { - } - - @Test - public void testGetTotal() { - } - -} -``` - -```java -public class InvoiceItemTest { - - @BeforeEach - public void setUp() { - } - - @AfterEach - public void tearDown() { - } - - @Test - public void testGetItemTotal() { - } - -} -``` \ No newline at end of file +1. Delete the test methods that are not related to the methods in the class diagram. You can also delete the constructors. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Test Coverage.md b/tiddlers/content/labs/lab02/_Labs_02_Test Coverage.md index d60f651..56da3e7 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Test Coverage.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Test Coverage.md @@ -1,4 +1,4 @@ -We haven't mentioned where JaCoCo fits in yet. JaCoCo is a code coverage tool. It monitors your system while it is being tested and can tell you which bits of your system were executed during the tests. NetBeans can show you the results by highlighting your code. +We haven't mentioned where JaCoCo fits in yet. JaCoCo is a test coverage tool. It monitors your system while it is being tested and can tell you which bits of your system were executed during the tests. NetBeans can show you the results by highlighting your code. This is a fairly crude way of quickly seeing where your tests are lacking --- code that isn't executed when the tests run is code that hasn't been tested. @@ -6,4 +6,4 @@ Now take a look at your `Invoice` class. You should see that some of the code is highlighted in green and some is red. The red bits are code that was not executed during the tests, and the green bits are the code that was. In this case the red bits are just simple getter methods, so we don't really care that we missed them in the tests. -Note: All that JaCoCo is telling us about code that is green is that it was executed during the test run --- this doesn't mean that the code has actually been tested. You need to have appropriate `assert` statements that check that the code is actually doing what it is supposed to be doing. This can often be quite difficult, particularly if your code is modifying the state of objects directly since we often can't directly access the private fields that hold that state to check the new values (since the fields are private) --- we will cover more advanced aspects of testing in INFO2lab02 next semester. \ No newline at end of file +
<> All that JaCoCo (and other code coverage tools) is telling us about code that is green is that it was executed during the test run --- this doesn't mean that the code has actually been tested. You need to have appropriate assert statements in the tests that check that the code is actually doing what it is supposed to be doing.

Basically, use code coverage tools to identify code that has been missed from tests --- but don't rely on the coverage percentages that they produce as a metric for test quality. You can get high coverage values by just calling each method in a class without using any assert statement to actually check anything. High coverage numbers do not mean quality tests.
\ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Testing Floating Point Numbers.md b/tiddlers/content/labs/lab02/_Labs_02_Testing Floating Point Numbers.md index e793fb3..8831821 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Testing Floating Point Numbers.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Testing Floating Point Numbers.md @@ -1,62 +1,32 @@ -We are using double precision floating point numbers here. Hopefully your remember from COMP101 that floating point numbers are not entirely precise (even the so-called double precision ones). We have been lucky so far, but let's see what happens if we get unlucky. +We are using double precision (64-bit) floating point numbers here. You should remember from COMP 101 that floating point numbers are not entirely precise (even the so-called double precision ones). We have been lucky so far, but let's see what happens if we get unlucky. -We will use the classic 0.1 and 0.2 values that show up the imprecision of floating point numbers very nicely. +We will use the classic 0.1 and 0.2 values that show up the imprecision of 64-bit floating point numbers very nicely. -Change the sale price in the `setUp` method to `0.1`, and the quantity purchased to `0.2`. +1. Change the sale price in the `setUp` method to `0.1`, and the quantity purchased to `0.2`. -The result of 0.1 * 0.2 is 0.lab02 in base 10. Modify the `testGetItemTotal` test to use `0.lab02` in the `is` method. +1. The result of 0.1 * 0.2 is 0.02 in base 10. Modify the `testGetItemTotal` test to use `0.02` in the `is` method. -Run the test. As expected, the evil 0.1 and 0.2 values have struck again. You can expand the arrows beside the test methods in the <> pane to see the explanation for the test failure: +1. Run the test. -``` -Expected: is <0.lab02> - but: was <0.lab020000000000000004> -``` + As expected, the evil 0.1 and 0.2 values have struck again. You can expand the arrows beside the test methods in the <> pane to see the explanation for the test failure: -How do we deal with this? We give the test some wiggle room to deal with precision errors. + ``` + Expected: is <0.02> + but: was <0.020000000000000004> + ``` -Modify the `assertThat` statement to: +1. How do we deal with this? We give the test some wiggle room to deal with precision errors. -```java -assertThat(result, is(closeTo(0.lab02, 0.0001))); -``` -The `0.0001` is how much error we are willing to accept. + Modify the `assertThat` statement to: -Fix the imports again to deal with the `closeTo` method. + ```java + assertThat(result, is(closeTo(0.02, 0.0001))); + ``` -Run the test again. We should be all good again. + The `0.0001` is how much error we are willing to accept. + + The value that you use for the error is dependent on your application --- if accumulated approxcimation error is something that you are worried about then you might choose a very small number here to ensure that approximation errors are being kept to a minimum. -The completed version of the class now looks like: +1. Fix the imports again to deal with the `closeTo` method. -```java -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.closeTo; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class InvoiceItemTest { - - private InvoiceItem item; - - @BeforeEach - public void setUp() { - item = new InvoiceItem(); - item.setProductName("Polkadot Widget"); - item.setSalePrice(0.1); - item.setQuantityPurchased(0.2); - } - - @AfterEach - public void tearDown() { - } - - @Test - public void testGetItemTotal() { - Double result = item.getItemTotal(); - assertThat(result, is(closeTo(0.lab02, 0.0001))); - } - -} -``` \ No newline at end of file +1. Run the test again. We should be all good again. diff --git a/tiddlers/content/labs/lab02/_Labs_02_Testing Invoice.md b/tiddlers/content/labs/lab02/_Labs_02_Testing Invoice.md index b08378f..4360e86 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Testing Invoice.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Testing Invoice.md @@ -1,83 +1,114 @@ -This lab is getting pretty long, so we will give you the entire test class for Invoice and point out the interesting bits. +This lab is getting pretty long, so we will give you the entire test class for `Invoice` and point out the interesting bits. -Again, if your original `InvoiceTest` file had a `package` declaration, then leave that in place, and replace the rest with the following: +If your original `InvoiceTest` file had a `package` declaration, then leave that in place, and replace the rest with the following: ```java import java.time.LocalDate; -import static org.hamcrest.CoreMatchers.hasItem; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.closeTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class InvoiceTest { - private Invoice invoice; - private InvoiceItem item1; - private InvoiceItem item2; + private Invoice invoice; + private InvoiceItem item1; + private InvoiceItem item2; + private InvoiceItem item3; - @BeforeEach - public void setUp() { - invoice = new Invoice(); - invoice.setCustomerName("Doris Delores"); - invoice.setCustomerAddress("123 Some Street, Some where"); - invoice.setDate(LocalDate.now()); + @BeforeEach + public void setUp() { + invoice = new Invoice(); + invoice.setCustomerName("Doris Delores"); + invoice.setCustomerAddress("123 Some Street, Some where"); + invoice.setDate(LocalDate.now()); - item1 = new InvoiceItem(); - item1.setProductName("Polkadot Widget"); - item1.setSalePrice(0.1); - item1.setQuantityPurchased(0.2); + item1 = new InvoiceItem(); + item1.setProductName("Polkadot Widget"); + item1.setSalePrice(0.1); + item1.setQuantityPurchased(0.2); - item2 = new InvoiceItem(); - item2.setProductName("Dodgy Doohicky"); - item2.setSalePrice(1.0); - item2.setQuantityPurchased(2.0); + item2 = new InvoiceItem(); + item2.setProductName("Dodgy Doohicky"); + item2.setSalePrice(1.0); + item2.setQuantityPurchased(2.0); - invoice.addItem(item1); - invoice.addItem(item2); - } + item3 = new InvoiceItem(); + item3.setProductName("Fuzzy Widget"); + item3.setSalePrice(1.1); + item3.setQuantityPurchased(2.2); - @AfterEach - public void tearDown() { - } + invoice.addItem(item1); + invoice.addItem(item2); - @Test - public void testAddItem() { - assertThat(invoice.getItems(), hasItem(item1)); - assertThat(invoice.getItems(), hasItem(item2)); - assertThat(invoice.getItems(), hasSize(2)); - } + //intentionally not adding item3 since it is added in testAddItem + } - @Test - public void testRemoveItem() { - invoice.removeItem(item1); - assertThat(invoice.getItems(), not(hasItem(item1))); - assertThat(invoice.getItems(), hasSize(1)); - } + @AfterEach + public void tearDown() { + } - @Test - public void testGetTotal() { - assertThat(invoice.getTotal(), is(closeTo(2.lab02, 0.0001))); - } + @Test + public void testAddItem() { + // make sure that item3 does not already exist + assertThat(invoice.getItems(), not(hasItem(item3))); + assertThat(invoice.getItems(), hasSize(2)); + + // add it + invoice.addItem(item3); + + // check that it was added + assertThat(invoice.getItems(), hasItem(item3)); + assertThat(invoice.getItems(), hasSize(3)); + } + + @Test + public void testRemoveItem() { + // make sure that item1 does already exist + assertThat(invoice.getItems(), hasItem(item1)); + assertThat(invoice.getItems(), hasSize(2)); + + // delete it + invoice.removeItem(item1); + + // make sure that it is gone + assertThat(invoice.getItems(), not(hasItem(item1))); + assertThat(invoice.getItems(), hasSize(1)); + } + + @Test + public void testGetTotal() { + assertThat(invoice.getTotal(), is(closeTo(2.02, 0.0001))); + } } ``` -! setUp method +### setUp method We are setting up the domain objects with initial state that we can test against. Basically, we are creating a complete invoice object that has a couple of items in it. -! testGetTotal test +### testGetTotal test There is nothing new here. We are dealing with floating point numbers again, so we use the `closeTo` method. -! testAddItem -We are using the `hasItem` method to check that the invoice's items collection has the two items that were added using the `addItem` method in the `setUp`. If so then the `addItem` method must have worked correctly. +### testAddItem +We want to be sure that the `addItem` method is actually adding the item, so we add a pre-condition check to verify that the item we are about to add doesn't already exist, which could cause the test to pass even if the `addItem` method is incorrect. -We are also checking the total size of the items collection with the `hasSize` method. This is useful to do since it catches bugs relating to left-over testing data that developers have forgotten about. +We are using the `hasItem` method to check that the invoice's `items` collection has the item that was added in the test. If so then the `addItem` method must have worked correctly. -! testRemoveItem -We are calling the invoice's `removeItem` method to remove `item1`, and then using the `hasItem` method to ensure that `item1` is no longer in the items collection. We are checking the size with `hasSize` again in case the `removeItem` method deleted more items than it should have. +We are also checking the total size of the `items` collection with the `hasSize` method. This is useful to do since it catches bugs relating to left-over testing data that developers have forgotten about, or a bad `tearDown` method that isn't properly cleaning up the test data. + +### testRemoveItem +Again, we have a pre-condition to make sure that the item that is going to be removed actually exists, so that we can be sure that the `removeItem` method is definitely the reason that the object is not present in the collection. + +We are then using the `hasItem` method to ensure that `item1` is no longer in the `items` collection after the `removeItem` method was called. + +Again, we are using `hasSize` to catch problems with the test data and to check that the `removeItem` method didn't remove more items than it should have, which might indicate a missing or incorrect `where` clause in the SQL `delete` statement (assuming we are using a database for storage, which we will be in future labs). Run the tests. All three tests should pass. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Testing InvoiceItem.md b/tiddlers/content/labs/lab02/_Labs_02_Testing InvoiceItem.md index a2e7a2f..d515dd2 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Testing InvoiceItem.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Testing InvoiceItem.md @@ -1,68 +1,33 @@ We will start with testing the `InvoiceItem` class. -Add the following field to the `InvoiceItemTest` class (remember that fields go at the top of the class, just under the first curly bracket). +1. Add a field that we will test against: -```java -private InvoiceItem item; -``` + ```java + private InvoiceItem item; + ``` -Add the following code to the `setUp` method: +1. Initialise the field in the `setUp` method: -```java -item = new InvoiceItem(); -item.setProductName("Polkadot Widget"); -item.setSalePrice(3.45); -item.setQuantityPurchased(2.0); -``` + ```java + item = new InvoiceItem(); + item.setProductName("Polkadot Widget"); + item.setSalePrice(3.45); + item.setQuantityPurchased(2.0); + ``` -Add the following to the `testGetItemTotal` method: + The `setUp` code is a little more complicated since we need to provide values for the initial state of the object. -```java -Double result = item.getItemTotal(); -assertThat(result, is(6.90)); -``` -Fix the imports using < Fix Imports">>. +1. Add test code to the `testGetItemTotal` method: -So far this is pretty similar to the calculator example. The `setUp` method is a little more complicated since we need to provide values for the initial state of the object. + ```java + Double result = item.getItemTotal(); + assertThat(result, is(6.90)); + ``` -Run the test. We now have more that one test in the project, so to run a specific test you should right-click the test class and select <>. You can either right-click the source code for the test class, or right-click the file in the <> pane. If you use the < Test Project">> menu item it will run all of the tests in the project, which is not what we want at the moment. +1. Fix the imports using < Fix Imports">>. -The test should pass. +1. Run the test. It should pass. -Validate the test by breaking the `getItemTotal` method in the `InvoiceItem` class, and run the test again. You can change the ``*`` operator to something else. The test should now fail. +1. Validate the test by breaking the `getItemTotal` method in the `InvoiceItem` class and run the test again. You can change the ``*`` operator to something else. The test should now fail. -Fix the method back up again. - -The completed version of this class looks like (ignoring comments and `package` declarations): - -```java -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class InvoiceItemTest { - - private InvoiceItem item; - - @BeforeEach - public void setUp() { - item = new InvoiceItem(); - item.setProductName("Polkadot Widget"); - item.setSalePrice(3.45); - item.setQuantityPurchased(2.0); - } - - @AfterEach - public void tearDown() { - } - - @Test - public void testGetItemTotal() { - Double result = item.getItemTotal(); - assertThat(result, is(6.90)); - } - -} -``` \ No newline at end of file +1. Fix the method again so that the test passes. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Testing the Add Method.md b/tiddlers/content/labs/lab02/_Labs_02_Testing the Add Method.md index 5f81e7a..5a05df4 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Testing the Add Method.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Testing the Add Method.md @@ -1,65 +1,35 @@ -Now we can properly implement the test for the `add` method. Replace the `fail` call with the following code in the `testAdd` method: +Now we can implement the test for the `add` method. -```java -// call the add method -Integer result = calc.add(3, 4); +1. **Replace** the `fail` call with the following code in the `testAdd` method: -// test that the add method returned the correct result -assertThat(result, is(7)); -``` + ```java + // call the add method + Integer result = calc.add(3, 4); -The complete `testAdd` method should look like: + // test that the add method returned the correct result + assertThat(result, is(7)); + ``` -```java -@Test -public void testAdd() { - // call the add method - Integer result = calc.add(3, 4); +2. Fix the imports (< Fix Imports">>) to import the `assertThat` and `is` methods. - // test that the add method returned the correct result - assertThat(result, is(7)); -} -``` +3. Run the test (right click the file in either the source editor, or project pane, and select <>. This time the `testAdd` method should pass. -Fix the imports again (< Fix Imports">>) to import the `assertThat` and `is` methods. +4. We aren't done with the `testAdd` method yet --- we need to check that our test is sufficient. Break the `add` method in the `Calculator` class by changing the `+` operator to a `-`. -Run the test. This time the `testAdd` method should pass. +5. Run the test again. You should see that the `testAdd` test now fails. This verifies that our test is capable of detecting when our method is returning an incorrect result. Fix the method again by putting the `+` operator back. -We aren't done with the `testAdd` method yet --- we need to check that our test is sufficient. Break the `add` method in the `Calculator` class by changing the `+` operator to a `-`. +6. This test still isn't all that comprehensive --- we have only tested one combination of numbers. Add the following to the `testAdd` method: -Run the test again. You should see that the `testAdd` test now fails. This verifies that our test is capable of detecting when our method is returning an incorrect result. Fix the method again by putting the `+` operator back. + ```java + assertThat(calc.add(1,2), is(3)); + assertThat(calc.add(5,-4), is(1)); + assertThat(calc.add(-5,4), is(-1)); + assertThat(calc.add(4,-8), is(-4)); + assertThat(calc.add(-1,-5), is(-6)); + ``` -This test still isn't all that comprehensive --- we have only tested one combination of numbers. Add the following to the `testAdd` method: + This should give the `add` method a good work out and also check that it can handle negative numbers for each parameter combination. We are cutting out the intermediate variable `result` here to make the code a little more compact. -```java -assertThat(calc.add(1,2), is(3)); -assertThat(calc.add(5,-4), is(1)); -assertThat(calc.add(-5,4), is(-1)); -assertThat(calc.add(4,-8), is(-4)); -assertThat(calc.add(-1,-5), is(-6)); -``` -This should give the `add` method a good work out and also check that it can handle negative numbers for each parameter combination. We are cutting out the intermediate variable `result` here to make the code a little more compact. + The `assertThat` and `is` methods are part of the Hamcrest library. Hamcrest provides a 'literate' interface for evaluating the results of tests. A literate interface is when you write code that reads a lot like spoken language (English in this case) --- "assert that 1+2 is 3". JUnit only has very basic `assert` methods built into it since it is expected that you will use something better like Hamcrest to evaluate the results. -The `assertThat` and `is` methods are part of the Hamcrest library. Hamcrest provides a 'literate' interface for evaluating the results of tests. A literate interface is when you write code that reads a lot like spoken language (English in this case) --- "assert that 1+2 is 3". JUnit has very basic `assert` methods built into it so it is expected that you will use something better like Hamcrest to evaluate the results. - -If any of these assertions are not true then the test will fail. - -The complete `testAdd` method at this point looks like: - -```java -@Test -public void testAdd() { - // call the add method - Integer result = calc.add(3, 4); - - // test that the add method returned the correct result - assertThat(result, is(7)); - - // test some other values - assertThat(calc.add(1,2), is(3)); - assertThat(calc.add(5,-4), is(1)); - assertThat(calc.add(-5,4), is(-1)); - assertThat(calc.add(4,-8), is(-4)); - assertThat(calc.add(-1,-5), is(-6)); -} -``` \ No newline at end of file + If any of these assertions are not true then the test will fail. diff --git a/tiddlers/content/labs/lab02/_Labs_02_Testing the Multiply Method.md b/tiddlers/content/labs/lab02/_Labs_02_Testing the Multiply Method.md index d026924..b4ca0dd 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Testing the Multiply Method.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Testing the Multiply Method.md @@ -1 +1 @@ -Using the `testAdd` test as an example, add tests to the `testMultiply` test to test the `multiply` method. Remember to test the test by intentionally breaking the `multiply` method. \ No newline at end of file +Using the `testAdd` test as an example, add tests to the `testMultiply` test to test the `multiply` method. Remember to test the test by intentionally breaking the `multiply` method in the `Calculator` class. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_Testing with Persistent Data.md b/tiddlers/content/labs/lab02/_Labs_02_Testing with Persistent Data.md index a8bf8e4..7d4012d 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_Testing with Persistent Data.md +++ b/tiddlers/content/labs/lab02/_Labs_02_Testing with Persistent Data.md @@ -2,10 +2,10 @@ We can simulate persistent state by making the `items` collection in the `Invoice` class `static`. -Modify the `Invoice` class so that the `items` field declaration now has the `static` keyword. The result looks like: +Modify the `Invoice` class so that the `items` field declaration now has the `static` keyword. The result should look like: ```java -private static Collection items = new ArrayList<>(); +private static Collection items = new HashSet<>(); ``` Static fields do not belong to any object --- they are part of the class itself. This means that any changes to the field will be reflected in all objects including brand new ones. All of our invoice objects will now all be sharing a single `items` collection. @@ -21,6 +21,11 @@ ```java invoice.removeItem(item1); invoice.removeItem(item2); +invoice.removeItem(item3); ``` -Run the tests again. We should be good again. \ No newline at end of file +Run the tests again. We should be good again. + +Run the tests a few more times to verify that the results are repeatable. + +Run the tests for the entire project by using < Test Project">>. We want to be sure that there are no weird interactions caused by tests interfering with each other. \ No newline at end of file diff --git a/tiddlers/content/labs/lab02/_Labs_02_The CalculatorTest Class.md b/tiddlers/content/labs/lab02/_Labs_02_The CalculatorTest Class.md index 329d602..b2c2e47 100644 --- a/tiddlers/content/labs/lab02/_Labs_02_The CalculatorTest Class.md +++ b/tiddlers/content/labs/lab02/_Labs_02_The CalculatorTest Class.md @@ -1,6 +1,6 @@ Let's take a look at the generated code. -## Default constructor +### Default constructor You will see a default constructor that looks like:
@@ -8,19 +8,17 @@ public CalculatorTest() { } ``` -You can identify a constructor by looking for a method that has the same name as the class. It will normally be the first method in the class (but it does not have to be). We are not going to be using this constructor, so delete it. -## `@BeforeEach` and `@AfterEach` methods +### `@BeforeEach` and `@AfterEach` methods You will also see two methods named `setUp` and `tearDown`. The method names really don't matter --- we tend to use these names through convention since early versions of JUnit required the methods to have these names. -It is the `@BeforeEach` and `@AfterEach` annotations above the methods that identify the method to JUnit. As mentioned in lecture 15 it is very important that each test is independent from every other test since we don't want tests to interfere with each other. These two methods will be run before and after each test. We can add set-up code to the `@BeforeEach` method and clean-up code to the `@AfterEach` method. +It is the `@BeforeEach` and `@AfterEach` annotations above the methods that identify the method to JUnit. As mentioned in lecture 2 it is very important that each test is independent from every other test since we don't want tests to interfere with each other. These two methods will be run before and after each test. We can add set-up code to the `@BeforeEach` method and clean-up code to the `@AfterEach` method. -## `@Test` methods +### `@Test` methods -You will see two methods named `testAdd` and `testMultiply`. Again, the names don't matter. For historical reasons we use the 'test' prefix for test methods. It is the `@Test` annotation that tells JUnit that this method is a test. +You will see two methods named `testAdd` and `testMultiply`. Again, the names don't matter, althought the methods do need to be `public` and `void`. For historical reasons we use the 'test' prefix for test methods. It is the `@Test` annotation that tells JUnit that this method is a test. You have probably already guessed that the code for testing the calculator's `add` method should go in the `testAdd` method, and the code for the `multiply` method should go in the `testMultiply` method. -
diff --git a/tiddlers/content/labs/lab02/_Labs_Lab 09_Diagrams_Invoice Class Diagram.tid b/tiddlers/content/labs/lab02/_Labs_Lab 09_Diagrams_Invoice Class Diagram.tid deleted file mode 100644 index fb18cfd..0000000 --- a/tiddlers/content/labs/lab02/_Labs_Lab 09_Diagrams_Invoice Class Diagram.tid +++ /dev/null @@ -1,40 +0,0 @@ -tags: lab02 lab hidden -title: /Labs/02/Diagrams/Invoice Class Diagram -type: text/vnd.tiddlywiki - -[[plantuml[ -@startuml - -skinparam { - style strictuml - roundCorner 5 - padding 2 - nodeSep 100 - class { - attributeIconSize 0 - fontSize 15 - } -} - -class "Invoice" as invoice { - - customerName : String - - customerAddress : String - - date : LocalDate --- - +addItem(itemToAdd : InvoiceItem) : void - +removeItem(itemToRemove : InvoiceItem) : void - +getTotal() : Double -} - -class "InvoiceItem" as item { - - productName : String - - salePrice : Double - - quantityPurchased : Double --- - + getItemTotal() : Double -} - -invoice -> "-items\r*" item - -@enduml -]]]