├── README.md ├── course-info.md ├── deliverables ├── 1 │ ├── deliverable1.md │ ├── grading_rubric.txt │ └── requirements.md ├── 2 │ ├── deliverable2.md │ ├── grading_rubric.txt │ ├── requirements.md │ └── sample_output.txt ├── 3 │ ├── TestRunner.java │ ├── deliverable3.md │ ├── grading_rubric.txt │ ├── requirements.md │ ├── selenium-java-2.52.0.zip │ └── selenium-server-standalone-2.52.0.jar ├── 4 │ ├── answers.txt │ ├── answers2.txt │ ├── deliverable4.md │ ├── elements.txt │ ├── grading_rubric.txt │ ├── sample_input.txt │ ├── sample_input2.txt │ └── sample_output.txt ├── 5 │ ├── checkstyle-7.0-all.jar │ ├── deliverable5.md │ ├── google_checks_modified.xml │ ├── grading_rubric.txt │ └── requirements.md └── 6 │ ├── deliverable6.md │ ├── file1.rpn │ ├── file2.rpn │ ├── file3.rpn │ ├── file4.rpn │ ├── file5.rpn │ ├── file6.rpn │ ├── file7.rpn │ └── grading_rubric.txt ├── exercises ├── 1 │ ├── GoatGoatCar.jar │ ├── exercise1.md │ └── requirements.md ├── 2 │ ├── LaboonCoin │ │ ├── LaboonCoin.java │ │ ├── LaboonCoinTest.java │ │ ├── TestRunner.java │ │ ├── hamcrest-core-1.3.jar │ │ └── junit-4.12.jar │ └── exercise2.md ├── 3 │ ├── Cat.java │ ├── CommandLineJunit │ │ ├── Badger.java │ │ ├── CoogieTest.java │ │ ├── Makefile │ │ ├── Noogie.java │ │ ├── NoogieTest.java │ │ ├── TestRunner.java │ │ ├── hamcrest-core-1.3.jar │ │ ├── junit-4.12.jar │ │ ├── mockito-core-1.10.19.jar │ │ └── objenesis-2.4.jar │ ├── RentACat.java │ ├── TestRunner.java │ ├── TestingWithMocks.md │ └── exercise3.md ├── 4 │ └── exercise4.md ├── 5 │ ├── exercise5.md │ └── sample_runs.txt ├── 6 │ └── exercise6.md └── 7 │ └── exercise7.md ├── lectures ├── CS1632_Lecture10_TDD.pdf ├── CS1632_Lecture12_Testable_Code.pdf ├── CS1632_Lecture13_PairwiseCombinatorial.pdf ├── CS1632_Lecture14_WebTestingSelenium.pdf ├── CS1632_Lecture15_JunitSelenium.pdf ├── CS1632_Lecture16_PerformanceTesting1.pdf ├── CS1632_Lecture17_PerformanceTesting2.pdf ├── CS1632_Lecture18_StaticAnalysis1.pdf ├── CS1632_Lecture19_StaticAnalysis2.pdf ├── CS1632_Lecture20_PropertyBasedTesting.pdf ├── CS1632_Lecture21_InteractingWithStakeholders.pdf ├── CS1632_Lecture22_TestingStrategy.pdf ├── CS1632_Lecture23_SecurityTesting.pdf ├── CS1632_Lecture2_Testing_Theory_and_Terminology.pdf ├── CS1632_Lecture3_Requirements.pdf ├── CS1632_Lecture4_Defects.pdf ├── CS1632_Lecture5_Breaking_Software.pdf ├── CS1632_Lecture6_Test_Plans.pdf ├── CS1632_Lecture7_Automated_Vs_Manual.pdf ├── CS1632_Lecture8_UnitTesting1.pdf └── CS1632_Lecture9_UnitTesting2.pdf ├── sample_code ├── CommandLineJunit │ ├── Badger.java │ ├── CoogieTest.java │ ├── Noogie.java │ ├── NoogieTest.java │ ├── TestRunner.java │ ├── hamcrest-core-1.3.jar │ ├── junit-4.12.jar │ ├── mockito-core-1.10.19.jar │ └── objenesis-2.4.jar ├── FloatingPointError.java ├── LinkedList.java ├── LinkedListTest.java ├── Node.java ├── TestRunner.java ├── heartbleed.c ├── runTests.sh └── selenium_example │ ├── README.md │ ├── RedditTest.java │ ├── RedditTestNoLogs.java │ ├── RedditTestRunner.java │ ├── RedditTestRunnerNoLogs.java │ ├── hamcrest-core-1.3.jar │ ├── junit-4.12.jar │ ├── run.sh │ ├── selenium-java-2.52.0.jar │ └── selenium-server-standalone-2.52.0.jar ├── study_guides ├── midterm_1_study_guide.md └── midterm_2_study_guide.md └── syllabus.md /README.md: -------------------------------------------------------------------------------- 1 | # CS1632_Fall2017 2 | CS1632 Software Quality Assurance at University of Pittsburgh, Fall 2017 Semester 3 | -------------------------------------------------------------------------------- /course-info.md: -------------------------------------------------------------------------------- 1 | # CS 1632 2 | Software Quality Assurance - Fall 2017 3 | 4 | ## Course Information 5 | 6 | **Taught by:** Bill Laboon (laboon at cs dot pitt dot edu) 7 | * GitHub username: laboon 8 | 9 | **Professor's Office Hours:** 10 | 11 | * SENSQ 6305 12 | * Tuesday, 1:30-4:30 (except first week) 13 | 14 | 15 | **Class Time:** 16 | * Mon / Wed, 9:30 AM - 10:45 AM 17 | 18 | **Room:** SENSQ 5129 19 | 20 | **TA**: 21 | 22 | Longhao Li - Github username: lilonghao720, email: lol16 at pitt dot edu 23 | 24 | TBD 25 | 26 | **Class GitHub repo:** https://www.github.com/laboon/CS1632_Fall2017 27 | **Required Text:** _A Friendly Introduction to Software Testing_ by Bill Laboon. 28 | * This is a PDF and is available on Github 29 | * https://github.com/laboon/software-testing/blob/master/software-testing-laboon-ebook.pdf 30 | * If you like, you may purchase a physical copy on Amazon at: http://www.amazon.com/Friendly-Introduction-Software-Testing/dp/1523477377/ or CreateSpace at: https://www.createspace.com/6008739 . 31 | * However, I want to emphasize that this is NOT NECESSARY. All material is available online, either in this repository or in the (freely available) PDF version of the book linked above. However, some people prefer to have a physical copy. 32 | 33 | **Recommended Texts:** 34 | 35 | _Test-Driven Development: By Example_, Kent Beck ISBN-13: 978-0321146533 36 | 37 | _Software Testing: A Craftsman's Approach_, Paul Jorgensen, ISBN-13: 978-1466560680 38 | 39 | I have both of these texts available for you to borrow. 40 | 41 | This course provides students with a broad understanding of modern software testing and quality assurance. Although it will cover testing theory, the emphasis is on providing practical skills in software testing currently used in industry. To that end, it will cover: manual and automated tests, test-driven development, performance testing, and understanding and developing a testing strategy. 42 | 43 | ## Grading 44 | 45 | * Projects (70%): 46 | * Deliverable 1 - 10% 47 | * Deliverable 2 - 15% 48 | * Deliverable 3 - 10% 49 | * Deliverable 4 - 10% 50 | * Deliverable 5 - 10% 51 | * Deliverable 6 - 15% 52 | * Midterms (20%): 53 | * Midterm 1 - 10% 54 | * Midterm 2 - 10% 55 | * Exercises (10%): 56 | * Includes several in-class exercises and lectures 57 | * See below 58 | 59 | Although you are not required to come to every class, it is strongly recommended that you do. 60 | 61 | Exercise days (where there is no lecture, but an in-class exercise) are listed on the syllabus as EX_n_ (where _n_ is in the range {1,7}). 62 | 63 | The following grading scale will be used. 64 | 65 | Score | Grade 66 | -----: | ------------------------------ 67 | 100.00-94.00 | A (A+ for extraordinary work) 68 | 93.99-91.00 | A- 69 | 90.99-88.00 | B+ 70 | 87.99-84.00 | B 71 | 83.99-81.00 | B- 72 | 80.99-78.00 | C+ 73 | 77.99-74.00 | C 74 | 73.99-71.00 | C- 75 | 70.99-68.00 | D+ 76 | 67.99-64.00 | D 77 | 63.99-61.00 | D- 78 | 60.99-0.00 | F 79 | 80 | All groups are expected to do their own work on the group projects, and students to do entirely their own work on the other projects. Projects may be analyzed with the Stanford _moss_ system to detect unauthorized collaboration between groups or individuals. Any student caught collaborating or cheating will automatically receive a 0 (zero) for that exam, and may be penalized more harshly based on University of Pittsburgh academic policy. 81 | 82 | Assignments should be committed and pushed to GitHub to _a private repository_ and shared with the TA and me by the beginning of class on the due date. Write-ups are due at the beginning of class and must be given to me in person. Late assignments will not be accepted absent of extraordinary circumstances. 83 | 84 | Please ensure that you have a student GitHub account so that you can make private repositories. This is free and available here: https://education.github.com/ 85 | 86 | If any disputes from groups arise, I will assume that GitHub is the "ground truth". For example, if Partner A insists that they did all the work, but GitHub history shows only commits by Partner B, I will assume that Partner B has done all the work. 87 | 88 | It is recommended you keep all of your graded assignments until final grades are posted and accepted, in order to resolve any discrepancies in grading. 89 | 90 | ## Attendance 91 | 92 | Lecture attendance for non-exercise classes is not required, but is STRONGLY recommended. The instructor will try to ensure that all information on the exams and projects will be available via slides, but simply reading them may be insufficient to understand the concepts thoroughly. Presence for exercise days is required in order to get the full class participation score. These will not be rescheduled individually. 93 | 94 | ## Project Details 95 | 96 | * **Deliverable 1:** A test plan and traceability matrix for a system. 97 | * **Deliverable 2:** Developing an application using unit tests. 98 | * **Deliverable 3:** Automated system-level tests of an application. 99 | * **Deliverable 4:** Performance testing and improvement of an application. 100 | * **Deliverable 5:** Developing a system with the help of static analysis. 101 | * **Deliverable 6:** Developing and testing a large application. 102 | 103 | ## Programming Language Selection 104 | 105 | For all deliverables, the class will use Java 1.8 or later with the appropriate frameworks (e.g., git, JUnit, Mockito, Selenium, FindBugs, checkstyle) as discussed in class. Projects written in other languages or using alternative frameworks will generally not be accepted. 106 | 107 | ## Participating in Class 108 | 109 | Under normal circumstances, it is almost always better to participate in class than not. Questions and comments are invited and strongly encouraged! However, this implies raising your hand and waiting to be called upon. In dire circumstances, some waving of the hands in order to get the instructor's attention is allowed, but suboptimal. Talking out of turn or while the instructor is speaking is frowned upon. If it persists after a warning has been given, the instructor may ask any offending parties to leave the room to continue their discussion elsewhere. 110 | 111 | ## Disability Services Statement 112 | 113 | "The Office of Disability Resources and Services (DRS) provides a broad range of support services to assist students with disabilities. Services include, but are not limited to, tape-recorded textbooks, sign language interpreters, adaptive and transportation. Contact DRS at 412-648-7890 or 412-383-1355 (TTY) in 216 William Pitt Union or see www.drs.pitt.edu for more computer technology, Braille translation, and nonstandard exam arrangements, DRS can also assist students with accessibility to campus housing information." 114 | 115 | ## Academic Integrity Statement 116 | 117 | The integrity of the academic process requires fair and impartial evaluation on the part of faculty and honest academic conduct on the part of students. To this end, students are expected to conduct themselves at a high level of responsibility in the fulfillment of the course of their study. It is the corresponding responsibility of faculty to make clear to students those standards by which students will be evaluated and the resources permissible for use by students during the course of their study and evaluation. The educational process is perceived as a joint faculty-student enterprise which will perforce involve professional judgment by faculty and may involve—without penalty—reasoned exception by students to the data or views offered by faculty. 118 | 119 | Cheating/plagiarism will not be tolerated. Students suspected of violating the University of Pittsburgh Policy on Academic Integrity, from the February 1974 Senate Committee on Tenure and Academic Freedom reported to the Senate Council, will be required to participate in the outlined procedural process as initiated by the instructor. A minimum sanction of a zero score for the quiz or exam will be imposed. 120 | 121 | View the complete policy at www.cfo.pitt.edu/policies/policy/02/02-03-02.html. 122 | -------------------------------------------------------------------------------- /deliverables/1/deliverable1.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 3 | 4 | * ASSIGNED: 11 SEP 2017 5 | 6 | * DUE: 20 SEP 2017 7 | 8 | ## Deliverable 1 9 | 10 | For this assignment, your group will determine a test plan for JBefunge, based on the requirements listed in the file requirements.md. Note that these are a _subset_ of all of the requirements of the program. There are several known defects in the software; you will need to find and report on at least three, as well as request one enhancement. Additionally, a traceability matrix showing the mapping of test cases to requirements is required. 11 | 12 | The JBefunge IDE repository is here: https://github.com/laboon/JBefunge 13 | 14 | Time will be given in class to group yourself into groups. There should be two and only two members of a group. 15 | 16 | There should be, at an absolute bare minimum, twice as many test cases as requirements, although I would normally expect several test cases per requirement. However, if the number of test cases is more than 4x the number of requirements, you are probably overtesting for our purposes. 17 | 18 | Each requirement should have AT LEAST one test case associated with it, and each test should have EXACTLY ONE requirement associated with it. This can easily be checked via a traceability matrix (which you should also deliver). Note that some test cases may actually test several requirements. You should specify the one that the test case fits best - that is, what are you really trying to test with this test case? 19 | 20 | Test cases should mention all necessary preconditions, execution steps, and postconditions. You do not need to separate out preconditions vs input values or postconditions vs output values for this test plan. 21 | 22 | It is NOT necessary to make multiple test plans inside a test suite; it is enough for there to be one test plan. 23 | 24 | I expect you to test three edge or corner cases as part of the test plan. These need to be marked in the description of the relevant test case. 25 | 26 | It is expected that you actually execute the test plan in order to find the defects, along with some exploratory testing to determine how the system works and where defects might lie. There are AT LEAST three defects. While you are not expected to find *all* of the defects, a reasonable test plan should definitely find at least three. This is an intentionally target-rich environment. 27 | 28 | You will also write up one request for enhancement to the program. This should be something that is _not_ specified in the requirements, but you, as a budding Befunge programmer, would like to see added to the IDE. 29 | 30 | ## Format 31 | Please hand in the paper to me with a cover page with: 32 | * The name of the project under test ("JBefunge") 33 | * The names of the people in the group 34 | * The title "CS 1632 - DELIVERABLE 1: Test Plan and Traceability Matrix" 35 | 36 | There should be a short introduction (a few paragraphs) in which you may note any concerns or difficulties you may have had or anticipate with the testing process. You should also note why you considered certain test cases, how you thought of edge cases, etc. 37 | 38 | This should be followed ON A NEW PAGE by the list of test cases. You may name or number them any way you wish, but be consistent. You should write them out in this format - 39 | 40 | IDENTIFIER: 41 | TEST CASE: 42 | PRECONDITIONS: 43 | EXECUTION STEPS: 44 | POSTCONDITIONS: 45 | 46 | The IDENTIFIER is some value which will UNIQUELY specify the test case. It should consist of some mnemonic (e.g. TEST-INVALID-TIMES, TEST-LOW-NUM-TIMES, etc.). 47 | 48 | ON A SEPARATE PAGE, a traceability matrix should be provided mapping the test cases with their associated requirements. Remember that all requirements should map to AT LEAST ONE test case (but usually more), and all test cases should map to EXACTLY ONE requirement. 49 | 50 | Finally, ON A SEPARATE PAGE, list at least three defects found. The defects should follow the defect reporting template: 51 | 52 | SUMMARY: 53 | DESCRIPTION: 54 | REPRODUCTION STEPS: 55 | EXPECTED BEHAVIOR: 56 | OBSERVED BEHAVIOR: 57 | SEVERITY: 58 | IMPACT: 59 | 60 | The test case which found the defect should be listed as part of the DESCRIPTION. 61 | 62 | The SEVERITY and IMPACT will obviously be a bit subjective; use your best judgment and explain why you believe that 63 | 64 | You may find it useful to review chapters 5 through 9 of the textbook. 65 | 66 | ## Grading 67 | * Introduction: 10% of grade 68 | * Test Plan: 45% of grade 69 | * Traceability Matrix: 10% of grade 70 | * Defects Found and Described: 35% of grade 71 | 72 | The requirements are listed in the file requirements.md. 73 | 74 | Please feel free to email me or come to office hours to discuss any problems you have. 75 | 76 | -------------------------------------------------------------------------------- /deliverables/1/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Grading Rubric for D1 2 | 3 | * Introduction: 10% of grade 4 | 5 | Concerns and/or difficulties listed: ____ / 5 6 | * At least one issue raised (-5 if no) 7 | 8 | Clearly written: ____ / 5 9 | * No typos / misspellings / etc 10 | * Understandable to reader (incl. clear sentence structure) 11 | 12 | * Test Plan: 45% of grade 13 | 14 | Test cases are valid ____ / 10 15 | * Include all elements 16 | * Identifier 17 | * Preconditions 18 | * Execution steps 19 | * Postconditions 20 | 21 | Test cases include only EXPECTED 22 | behavior, not OBSERVED behavior: ____ / 10 23 | * No "pass/fail" etc. written 24 | * Postconditions = what SHOULD happen, not what DOES 25 | * Test correct (expected) behavior 26 | 27 | Expected behavior and execution 28 | steps are SPECIFIC: ____ / 15 29 | * No generalities (e.g. "enter a letter"; should be "enter X") 30 | * Tester could easily reproduce steps 31 | 32 | At least three edge cases: ____ / 5 33 | * Valid edge cases and labeled 34 | 35 | Clearly written: ____ / 5 36 | * No typos, misspellings, etc. (-1 for each) 37 | * Easy to understand and follow 38 | 39 | * Traceability Matrix: 10% of grade 40 | 41 | Each requirement & TC listed: ____ / 5 42 | * TCs actually map to requirement 43 | 44 | >= 1 Test case per requirement, and 45 | exactly 1 requirement per TC: ____ / 5 46 | * No TC maps to > 1 req, each req has at least 1 TC 47 | 48 | * Defects and Enhancements Found and Described: 35% of grade 49 | 50 | Must be >= 3 defects! -10 for each missing one. 51 | 52 | Defects are Reproducible: ____ / 10 53 | * Specific steps to repro listed 54 | 55 | Include expected/observed behavior: ____ / 10 56 | * Must include BOTH 57 | 58 | Enhancement included: _____ / 10 59 | * Is an enhancement, not a defect 60 | * Is a reasonable, well-defined request 61 | 62 | Clearly written: ____ / 5 63 | * No typos, misspellings, etc. 64 | * Reader can understand issue 65 | * Follows proper format 66 | 67 | Total: ____ / 100 68 | -------------------------------------------------------------------------------- /deliverables/1/requirements.md: -------------------------------------------------------------------------------- 1 | FUN-TEXT-DISPLAY - Upon startup, the system shall display a graphical user interface with three textboxes, labeled Program Area, Stack, and Output. The Program Area textbox shall be user-editable; the other two will never be editable directly by the user. 2 | 3 | FUN-MENUS - There shall be three menu groups: File, Color, and Options. Under File, there shall be four menu items: Open File, Save File, Save As, and Quit. Under Color, there shall be six menu items: Red, Yellow, Blue, Pink, Green, and Orange. Under Options, there shall be two checkable menu items: Time Program, and Check for End Opcode. 4 | 5 | FUN-BEFUNGE - The system shall be able to run any valid Befunge-93 program, displaying valid stack data and output according to the Befunge-93 specification here: http://catseye.tc/view/befunge-93/doc/Befunge-93.markdown 6 | 7 | FUN-RUN-SPEED - The system shall have three standard execution speeds, Run (no pauses in execution), Walk (50 ms pause after each opcode), and Mosey (500 ms pause after each opcode). All of these shall be reachable by pressing a button of the appropriate name. 8 | 9 | FUN-STEP - The system shall allow the user to step one opcode at a time, appropriately updating the stack and output, by pressing the Step button. 10 | 11 | FUN-STOP - When no program is being executed, the Stop button shall be disabled. When a program is being executed, the Stop button shall be enabled. Upon clicking the Stop button, the currently running program shall stop execution. 12 | 13 | FUN-TIME - If the "Options..Time program" option is checked, then after program execution has completed, the system shall inform the user how long, in microseconds, the program took to execute. If the "Options..Time Program" option is not checked, the user shall not be informed. 14 | 15 | FUN-TRACE - If and only if a program is being executed, the system shall display a cursor on the current opcode indicating that is being executed. This cursor should start displaying immediately after starting execution of a program on the first opcode, and will do so no matter if started via Run, Walk, Mosey, or Step. It shall not appear when a program is not being executed. 16 | 17 | FUN-CHECK-END-OPCODE - If the "Options...Check For End Opcode" option is checked, then the system shall warn the user if no end opcode ("@" character) exists in the Program Area. If an end opcode does exist, even if it is unreachable, no warning will be shown. 18 | 19 | PERF-EXECUTION-TIME - On any given computer, the system shall be able to complete execution of a reference FizzBuzz implementation (i.e., the one listed in the README.md file of the JBefunge repository), in less than 30 seconds (30,000,000 microseconds). 20 | 21 | -------------------------------------------------------------------------------- /deliverables/2/deliverable2.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 3 | DUE 10 OCT 2017 4 | 5 | ## Deliverable 2 6 | 7 | For this assignment, you (not a group) will write code and unit tests for CitySim9005. 8 | 9 | Requirements for this program are in the requirements.txt file in this directory. Sample output is also provided for several runs of the program. In case of ambiguity, please see the sample output as an example of what to display and how the system should work. Note that the sample output shows specific routes for given seeds - you do NOT have to have your seeds create the exact same routes. They are purely for demonstration purposes. 10 | 11 | All code and tests should be on GitHub or GitLab in a private repository accessible to me. 12 | 13 | ## Format 14 | You should turn in a title page with: 15 | * Your name 16 | * The URL of your code and tests on GitHub or GitLab 17 | * The title "CS 1632 - DELIVERABLE 2: Unit Testing CitySim9005" 18 | 19 | ENSURE THAT THE THE TA AND I ARE ADDED AS A COLLABORATOR AND CAN CLONE YOUR REPOSITORY! My username is `laboon` on both GitHub and Gitlab. The TA's username will be emailed to you shortly - it is `lilonghao720`. You will lose an automatic 10 points if either I or the TA cannot access your repository. If you are using GitLab instead of GitHub, please just add me as a collaborator (username is still laboon), not the TA. 20 | 21 | Add a short ( < 1 page ) description of issues you faced when writing this code and tests. If any tests you wrote fail, they should be included here, along with why you think that they are failing. 22 | 23 | After this, ON A SEPARATE PAGE, include a screen shot of the executed unit tests. If a test doesn't pass, it should be included in the concerns section above. Ideally, for a perfect grade, all tests should be green (passing). However, if you have what you think is a valid test and it is not passing, I would prefer that you include a note (and perhaps comment out the tests) rather than just deleting it. Knowing that a defect exists and reporting it is much better than having it discovered by the customer (me)! 24 | 25 | There is no need to print out the code itself. It should be on GitHub (or GitLab) BY THE BEGINNING OF CLASS. 26 | 27 | At least three (3) unit tests should use test doubles and/or mocks. 28 | 29 | At least three (3) unit tests should use stubbing of methods. 30 | 31 | I expect unit tests for AT LEAST each public method that returns a value (excluding the main method), using a variety of assertions and looking at different failure modes and edge cases. Keep in mind some of the things we learned when doing manual testing; you should be cognizant of equivalence classes, boundary values, etc. and focus on them. 32 | 33 | The program should use appropriate object-oriented design. Think of what objects could possibly exist to describe this world, and what methods they should have. Do not attempt to do this entirely with static methods and variables, without classes, etc. It is possible but will make testing more difficult! 34 | 35 | If you are not familiar with seeds for random number generators, recall that in the absence of external input, a computer can only generate data deterministically. This seed will act as our "external input". Please review the Java Random API for more details to ensure that you are using seeds correctly - https://docs.oracle.com/javase/7/docs/api/java/util/Random.html. You may use Random or a different random number generator if you prefer. However, running your program twice with the same seed should always produce the same output. 36 | 37 | Before each test, add some comments (two or three sentences, on average) explaining what the test is checking. For example... 38 | 39 | ```java 40 | // Two LLs with different sizes should never be equal. 41 | // Create two linked lists, both of which have the same value in the initial node, 42 | // but one has several more nodes. 43 | // They should not be equal to each other. 44 | @Test 45 | public void testNotEqualsDiffSizes() { 46 | LinkedList ll11 = new LinkedList(); 47 | LinkedList ll_3elems = new LinkedList(); 48 | 49 | ll11.addToFront(new Node(new Integer(1))); 50 | ll_3elems.addToFront(new Node(new Integer(3))); 51 | ll_3elems.addToFront(new Node(new Integer(2))); 52 | ll_3elems.addToFront(new Node(new Integer(1))); 53 | 54 | assertFalse(ll_3elems.equals(ll11)); 55 | } 56 | ``` 57 | 58 | ## Grading 59 | I remind you that grammar and good code count as well as functionality. By good code, I mean - 60 | 61 | No commented-out code unless there's an EXPLICIT reason, e.g. 62 | ```java 63 | // I couldn't get this assertion to work, but instead used a different assertion, below 64 | // assertEquals(foo, 3); 65 | assertTrue(foo == 3); 66 | ``` 67 | 68 | Properly indented code, e.g. 69 | ```java 70 | public void doSomething() { 71 | doStuff(); 72 | } 73 | ``` 74 | NOT 75 | ```java 76 | public 77 | void 78 | doSomething() 79 | { doStuff(); } 80 | ``` 81 | 82 | Don't misspell words or use bad grammar, in comments or summaries. 83 | 84 | For this project, you should endeavour to get a good sampling of different equivalence classes and success/failure cases. 85 | 86 | ## Grading Breakdown 87 | * Summary and Testing Concerns- 10% 88 | * Screenshot of executed unit tests - 10% 89 | * Program Code - 40% 90 | * Test Code - 40% 91 | 92 | Please feel free to email me or come to office hours to discuss any problems you have. 93 | -------------------------------------------------------------------------------- /deliverables/2/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Summary (10%): _____ / 10 2 | * No typos or grammatical errors (only up to -4) 3 | * Describe at least one issue 4 | 5 | Screenshot of executed unit tests (10%): _____ / 10 6 | 7 | Program code (40%): 8 | 9 | Proper argument conditions (ceases execution cleanly 10 | if incorrect type or wrong number) : _____ / 10 11 | * Should not run with 0 arguments ( -3 ) 12 | * Should not run with >1 arguments ( -3 ) 13 | * Does not crash w/ invalid input (-4 ) 14 | 15 | Seed accepted (reproducible w/ same seed): _____ / 5 16 | * Multiple times w/ same seed, same output (-5 if not) 17 | * Running w/ diff seeds means diff output (-5 if not) 18 | 19 | Drivers follow valid paths: _____ / 15 20 | * Cars always go in proper directions down streets (-5) 21 | * Cars always end up going to Philadelphia or Cleveland (-5) 22 | 23 | Proper display output: _____ / 5 24 | * Display generally matches sample output (up to -5) 25 | 26 | Good object-oriented style: _____ / 5 27 | * Classes with proper methods representing objects (up to -5) 28 | 29 | Test Code (40%): 30 | 31 | Public methods tested: _____ / 15 32 | * All tests must have assertions (-3 for each one that is not) 33 | * All tests must be annotated w/ @Test (-3 for each one that is not) 34 | * All tests should be passing (-3 for each one that is not) 35 | 36 | Edge cases tested: _____ / 5 37 | * At least three true edge cases checked (0: -5, 1: -4, 2: -3) 38 | 39 | At least 3 doubles used: _____ / 5 40 | * Proper doubles / or mocks used (0: -5, 1: -4, 2: -3) 41 | 42 | At least 3 stubs used: _____ / 5 43 | * Proper stubs used (0: -5, 1: -4, 2: -3) 44 | 45 | Good style: _____ / 10 46 | * All tests properly commented with descriptions (-3 each if not, up to -9) 47 | * No gratuitously ugly, superfluous, or commented code (up to -5) 48 | 49 | If tests cannot run, 20 points for this section MAXIMUM. 50 | 51 | ----- 52 | 53 | Submission issues (-10) or other adjustments: _____ 54 | 55 | Total: _____ / 100 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /deliverables/2/requirements.md: -------------------------------------------------------------------------------- 1 | ## CitySim9005 Requirements 2 | 3 | FUN-CITY-LOCS. The program shall simulate a city with four locations: Hotel, Diner, Library, and Coffee. 4 | 5 | FUN-OUTSIDE-CITY. A fifth location, Outside City, shall stand for a driver outside the city limits. 6 | 7 | FUN-AVENUES. The city shall have two one-way avenues, Fourth Ave and Fifth Ave. Fourth Ave shall connect, in order, Outside City -> Hotel -> Diner -> Outside City. Fifth Ave shall connect, in order, Outside City -> Coffee -> Library -> Outside City. 8 | 9 | FUN-STREETS. The city shall have two two-way streets, Bill St. and Phil St. Bill St. shall connect Hotel and Library. Phil St. shall connect Diner and Coffee. 10 | 11 | FUN-FIVE-DRIVERS. Five drivers, numbered 1 through 5, shall traverse the city, one after the other. 12 | 13 | FUN-START-LOC. A driver may start in any of the four locations listed in FUN-CITY-LOCS. Drivers may not start outside of the city. 14 | 15 | FUN-ITERATION. At each iteration, a Driver will drive from the current Location to one of the possible Locations that can be reached from the original Location. The decision shall be made pseudorandomly based on a seed passed in from the command line, as covered by FUN-ARGS. 16 | 17 | FUN-END. The simulation shall end if a Driver encounters the Outside City Location. 18 | 19 | FUN-ARGS. The system shall accept an integer seed from the command line for the pseudorandom number generator. No other arguments shall be accepted. If no arguments are provided, more than one argument is provided, or the single argument is not a valid Java 32-bit integer, the system shall inform the user and exit. 20 | 21 | FUN-OTHER-CITIES. If a driver exits the city via Fourth Avenue (that is, goes to the Outside City location past the Diner), then the program shall display that the driver has gone to Philadelphia. If a driver exits the city via Fifth Avenue (that is, goes to the Outside City location past the Library), then the program shall display that the driver has gone to Cleveland. 22 | 23 | It may be easier to understand the map of the city visually. 24 | 25 | ``` 26 | City Map 27 | 28 | ---> [Hotel] ----> [Diner] ----> Fourth Ave. (to Philadelphia) 29 | ^ | ^ | 30 | Bill St.| | | | Phil St. 31 | | V | V 32 | (to Cleveland) <--- [Library] <-- [Coffee] <--- Fifth Ave. 33 | ``` 34 | -------------------------------------------------------------------------------- /deliverables/2/sample_output.txt: -------------------------------------------------------------------------------- 1 | $ java CitySim9005 1 2 | Driver 1 heading from Coffee to Library via Fifth Ave. 3 | Driver 1 heading from Library to Hotel via Bill St. 4 | Driver 1 heading from Hotel to Diner via Fourth Ave. 5 | Driver 1 heading from Diner to Coffee via Phil St. 6 | Driver 1 heading from Coffee to Diner via Phil St. 7 | Driver 1 heading from Diner to Outside City via Fourth Ave. 8 | Driver 1 has gone to Philadelphia! 9 | ----- 10 | Driver 2 heading from Library to Hotel via Bill St. 11 | Driver 2 heading from Hotel to Diner via Fourth Ave. 12 | Driver 2 heading from Diner to Coffee via Phil St. 13 | Driver 2 heading from Coffee to Diner via Phil St. 14 | Driver 2 heading from Diner to Outside City via Fourth Ave. 15 | Driver 2 has gone to Philadelphia! 16 | ----- 17 | Driver 3 heading from Diner to Outside City via Fourth Ave. 18 | Driver 3 has gone to Philadelphia! 19 | ----- 20 | Driver 4 heading from Library to Hotel via Bill St. 21 | Driver 4 heading from Hotel to Diner via Fourth Ave. 22 | Driver 4 heading from Diner to Coffee via Phil St. 23 | Driver 4 heading from Coffee to Diner via Phil St. 24 | Driver 4 heading from Diner to Coffee via Phil St. 25 | Driver 4 heading from Coffee to Diner via Phil St. 26 | Driver 4 heading from Diner to Outside City via Fourth Ave. 27 | Driver 4 has gone to Philadelphia! 28 | ----- 29 | Driver 5 heading from Coffee to Library via Fifth Ave. 30 | Driver 5 heading from Library to Hotel via Bill St. 31 | Driver 5 heading from Hotel to Diner via Fourth Ave. 32 | Driver 5 heading from Diner to Outside City via Fourth Ave. 33 | Driver 5 has gone to Philadelphia! 34 | ----- 35 | 36 | $ java CitySim9005 10 37 | Driver 1 heading from Coffee to Diner via Phil St. 38 | Driver 1 heading from Diner to Coffee via Phil St. 39 | Driver 1 heading from Coffee to Diner via Phil St. 40 | Driver 1 heading from Diner to Outside City via Fourth Ave. 41 | Driver 1 has gone to Philadelphia! 42 | ----- 43 | Driver 2 heading from Coffee to Diner via Phil St. 44 | Driver 2 heading from Diner to Coffee via Phil St. 45 | Driver 2 heading from Coffee to Diner via Phil St. 46 | Driver 2 heading from Diner to Coffee via Phil St. 47 | Driver 2 heading from Coffee to Library via Fifth Ave. 48 | Driver 2 heading from Library to Hotel via Bill St. 49 | Driver 2 heading from Hotel to Library via Bill St. 50 | Driver 2 heading from Library to Outside City via Fifth Ave. 51 | Driver 2 has gone to Cleveland! 52 | ----- 53 | Driver 3 heading from Coffee to Diner via Phil St. 54 | Driver 3 heading from Diner to Coffee via Phil St. 55 | Driver 3 heading from Coffee to Diner via Phil St. 56 | Driver 3 heading from Diner to Outside City via Fourth Ave. 57 | Driver 3 has gone to Philadelphia! 58 | ----- 59 | Driver 4 heading from Coffee to Library via Fifth Ave. 60 | Driver 4 heading from Library to Hotel via Bill St. 61 | Driver 4 heading from Hotel to Diner via Fourth Ave. 62 | Driver 4 heading from Diner to Outside City via Fourth Ave. 63 | Driver 4 has gone to Philadelphia! 64 | ----- 65 | Driver 5 heading from Diner to Outside City via Fourth Ave. 66 | Driver 5 has gone to Philadelphia! 67 | ----- 68 | 69 | 70 | $ java CitySim9005 111 71 | Driver 1 heading from Coffee to Library via Fifth Ave. 72 | Driver 1 heading from Library to Outside City via Fifth Ave. 73 | Driver 1 has gone to Cleveland! 74 | ----- 75 | Driver 2 heading from Hotel to Library via Bill St. 76 | Driver 2 heading from Library to Hotel via Bill St. 77 | Driver 2 heading from Hotel to Diner via Fourth Ave. 78 | Driver 2 heading from Diner to Outside City via Fourth Ave. 79 | Driver 2 has gone to Philadelphia! 80 | ----- 81 | Driver 3 heading from Hotel to Library via Bill St. 82 | Driver 3 heading from Library to Hotel via Bill St. 83 | Driver 3 heading from Hotel to Diner via Fourth Ave. 84 | Driver 3 heading from Diner to Coffee via Phil St. 85 | Driver 3 heading from Coffee to Diner via Phil St. 86 | Driver 3 heading from Diner to Coffee via Phil St. 87 | Driver 3 heading from Coffee to Diner via Phil St. 88 | Driver 3 heading from Diner to Coffee via Phil St. 89 | Driver 3 heading from Coffee to Diner via Phil St. 90 | Driver 3 heading from Diner to Coffee via Phil St. 91 | Driver 3 heading from Coffee to Library via Fifth Ave. 92 | Driver 3 heading from Library to Hotel via Bill St. 93 | Driver 3 heading from Hotel to Library via Bill St. 94 | Driver 3 heading from Library to Hotel via Bill St. 95 | Driver 3 heading from Hotel to Library via Bill St. 96 | Driver 3 heading from Library to Hotel via Bill St. 97 | Driver 3 heading from Hotel to Library via Bill St. 98 | Driver 3 heading from Library to Hotel via Bill St. 99 | Driver 3 heading from Hotel to Library via Bill St. 100 | Driver 3 heading from Library to Outside City via Fifth Ave. 101 | Driver 3 has gone to Cleveland! 102 | ----- 103 | Driver 4 heading from Diner to Coffee via Phil St. 104 | Driver 4 heading from Coffee to Library via Fifth Ave. 105 | Driver 4 heading from Library to Outside City via Fifth Ave. 106 | Driver 4 has gone to Cleveland! 107 | ----- 108 | Driver 5 heading from Coffee to Library via Fifth Ave. 109 | Driver 5 heading from Library to Outside City via Fifth Ave. 110 | Driver 5 has gone to Cleveland! 111 | ----- 112 | 113 | $ java CitySim9005 arglebargle 114 | Please enter one integer argument. 115 | 116 | $ java CitySim9005 1 6 700 117 | Please enter one integer argument. 118 | 119 | $ java CitySim9005 120 | Please enter one integer argument. 121 | 122 | -------------------------------------------------------------------------------- /deliverables/3/TestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class TestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(Foo.class); 15 | 16 | // For all test classes added, loop through and use JUnit 17 | // to run them. 18 | 19 | for (Class c: classesToTest) { 20 | Result r = JUnitCore.runClasses(c); 21 | 22 | // Print out any failures for this class. 23 | 24 | for (Failure f : r.getFailures()) { 25 | System.out.println(f.toString()); 26 | } 27 | 28 | // If r is not successful, there was at least one 29 | // failure. Thus, set anyFailures to true - this 30 | // can never be set back to false (no amount of 31 | // successes will ever eclipse the fact that there 32 | // was at least one failure. 33 | 34 | if (!r.wasSuccessful()) { 35 | anyFailures = true; 36 | } 37 | 38 | } 39 | 40 | // After completion, notify user if all tests passed or any failed. 41 | 42 | if (anyFailures) { 43 | System.out.println("\n!!! - At least one failure, see above."); 44 | } else { 45 | System.out.println("\nALL TESTS PASSED"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /deliverables/3/deliverable3.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 3 | 4 | DUE 30 OCT 2017 5 | 6 | ## Deliverable 3 7 | 8 | For this assignment, you and a partner will write systems-level, automated black-box tests for a web app using Selenium and JUnit. 9 | 10 | Test code should be on a private repository and GitHub, and the TA and myself should be added as collaborators by the beginning of class on the due date. 11 | 12 | Please use the included TestRunner and Selenium jars. You may modify the TestRunner class to include any test classes that you have created. These are _not_ the latest Selenium jars, but they are guaranteed to work together. 13 | 14 | The web app is located here: https://cs1632ex.herokuapp.com/ 15 | 16 | This is an Elixir/Phoenix application. If you like, you may look at the source code here: https://github.com/laboon/cs1632d3ex. However, this is NOT necessary (and technically would make this grey-box testing). I do not expect you to learn yet another language for this course. It might be interesting for you to see Elixir code, though (it is slightly more useful than learning Befunge). 17 | 18 | ## Format 19 | Everyone should have a title page with: 20 | * Your name 21 | * The URL of your code and tests on GitHub 22 | * The title "CS 1632 - DELIVERABLE 3: Unit Testing" 23 | 24 | For the summary, add a description of issues you faced when writing these tests and problems you would expect going forward based on your experiences. If any tests you wrote fail (some should!), they should be included here. 25 | 26 | After this, there should be a printout or screen shot of the test execution results. 27 | 28 | There is no need to print out the code. It should be shared with me and the TA (i.e., we have been added as collaborators) on GitHub BY THE BEGINNING OF CLASS. 29 | 30 | The JUnit tests shall have a description (a few sentences at most) of what they are testing written in the comments above the particular test. See RedditTest.java in the sample_code directory for an example. 31 | 32 | Remember these are USER-level systems tests; comments should describe tests in a way that an intelligent user of the software would understand. Even though we are using JUnit, these are _not_ unit tests. Remember the differences between system-level tests and unit tests! 33 | 34 | There should be a bare minimum of twenty tests, checking various base, edge, and corner cases. There is a maximum of thirty tests. However, do not focus on the number of tests too heavily; I am more concerned that you cover a broad variety of cases, check the requirements, and ones which are focused and yet still likely to find defects. 35 | 36 | ## Note on Selenium Drivers 37 | 38 | Please use the following Selenium jars. They are also included in this directory in the repository. 39 | 40 | 2.52 Selenium Server jar: http://selenium-release.storage.googleapis.com/2.52/selenium-server-standalone-2.52.0.jar 41 | 42 | 2.52 Java bindings jar: http://selenium-release.storage.googleapis.com/2.52/selenium-java-2.52.0.zip 43 | 44 | ## Note on Firefox / Selenium in Windows 45 | 46 | To open the Selenium IDE from Firefox in Windows, right click the top bar of firefox, between the open tabs and the minimize button. Click "Menu Bar" so the menu bar shows up in the top left corner. Under "Tools" is "Selenium IDE". 47 | 48 | Alternatively, "ctrl+alt+s" while in the Firefox window should also bring up the IDE. 49 | 50 | ## Requirements 51 | 52 | Requirements for the application are listed in the `requirements.md` file in this directory. 53 | 54 | Remember to check for implicit as well as explicit requirements! 55 | 56 | You should have at least one test for each requirement. 57 | 58 | ## Defects 59 | 60 | This is another buggy product. You should find at least three defects and report them using the standard defect template (just like in the first deliverable). These defects should be detected by your automated tests (i.e., there should be at least _three_ failures of your tests). 61 | 62 | You may want to do some exploratory testing first to see what kind of issues are found before writing automated tests for them. 63 | 64 | ## Traceability Matrix 65 | 66 | Please make a traceability matrix (just as in the first deliverable). Tests should be identified by the name of the test case method (e.g., `public void testFoo()` should be indicated on the matrix as `testFoo`). 67 | 68 | ## Grading 69 | * Summary and Testing concerns - 5% 70 | * Screen shot or printout of test results - 5% 71 | * Proper comment descriptions of tests - 10% 72 | * JUnit Tests - 45% 73 | * Defect reports - 25% 74 | * Traceability matrix - 10% 75 | 76 | Please feel free to email me or come to office hours to discuss any problems you have. 77 | 78 | -------------------------------------------------------------------------------- /deliverables/3/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Summary and testing concerns (5%): 2 | 3 | Summary and concerns: _____ / 5 4 | * Specify any issues had by student (-4 if not) 5 | * More than one typo, -1 per each (up to -3) 6 | 7 | Screenshot of executed unit tests (5%): _____ / 5 8 | 9 | Comment descriptions of tests (10%): 10 | 11 | Test comment quality : _____ / 10 12 | * Explain what the test is testing (-2 for each 13 | that does not, or -3 if egregious, e.g. blank) 14 | 15 | JUnit tests (45%): 16 | 17 | Maximum 10/50 if tests written but cannot compile/run! 18 | 19 | Tests compile and execute: _____ / 5 20 | 21 | Happy path cases checked: _____ / 15 22 | * At least five "normal" happy path cases 23 | 24 | Edge cases checked: _____ / 10 25 | * At least two edge cases checked 26 | 27 | Defects caught: _____ / 10 28 | * At least three tests should fail and they 29 | should line up with the reported defects (-3 for each not) 30 | 31 | Good style: _____ / 5 32 | * No gratuitously ugly, superfluous, or commented code (up to -5) 33 | 34 | Defects (25%): 35 | 36 | If not at least three defects, maximum 10/25 on this section 37 | 38 | Three valid defects found: _____ / 10 39 | * Defect lines up with failed unit test (-2 if not) 40 | * Defect actually occurs (-5 if not) 41 | 42 | Defects reported properly: _____ / 15 43 | * Expected behavior / observed behavior / repro steps (-4 for each 44 | test case incorrectly reported) 45 | * General quality (well-specified, well-written) 46 | 47 | Traceability Matrix _____ / 10 48 | * Has 49 | ----- 50 | 51 | Submission issues (-10) or other adjustments: _____ 52 | 53 | Total: _____ / 100 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /deliverables/3/requirements.md: -------------------------------------------------------------------------------- 1 | ## App homepage: https://cs1632ex.herokuapp.com/ 2 | 3 | 1. The homepage shall display the text "Welcome, friend, to a land of pure calculation" as well as "Used for CS1632 Software Quality Assurance, taught by Bill Laboon" 4 | 2. Every page shall include five links at the top, to "CS1632 D3 Home", "Factorial", "Fibonacci", "Hello", and "Cathedral Pics". These shall link to `/`, `/fact`, `/fib`, `/hello`, and `/cathy`, respectively. 5 | 3. The factorial page (`/fact`) shall allow a user to enter a positive integer from 1 to 100, and upon pressing submit, shall show to the user the factorial of the value (e.g. "Factorial of 5 is 120!"). 6 | 4. The Fibonacci page (`/fib`) shall allow a user to enter a positive integer from 1 to 100, and upon pressing submit, shall show to the user the Fibonnaci of the value (e.g. "Fibonacci of 5 is 8!"). 7 | 5. For both the Fibonacci and Factorial pages, if a user enters an invalid value of any kind, they shall be informed that the value is 1 (e.g., "Fibonacci of -100 is 1!") 8 | 6. Accessing the hello page (`/hello`) with no trailing values in the URL shall display the message "Hello CS1632, from Prof. Laboon!". 9 | 7. If a trailing value is provided in the URL when accessing the `/hello` page, then the message shall display hello from that trailing value. For example, when accessing `/hello/Jazzy`, the system shall display "Hello CS1632, from Jazzy!". This shall work for all input values. 10 | 8. The Cathedral page (`/cathy`) shall display three images of the Cathedral of Learning in a numbered list. 11 | -------------------------------------------------------------------------------- /deliverables/3/selenium-java-2.52.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/deliverables/3/selenium-java-2.52.0.zip -------------------------------------------------------------------------------- /deliverables/3/selenium-server-standalone-2.52.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/deliverables/3/selenium-server-standalone-2.52.0.jar -------------------------------------------------------------------------------- /deliverables/4/answers.txt: -------------------------------------------------------------------------------- 1 | John Jacob Jingleheimer Schmidt 2 | Could not create name "John Jacob Jingleheimer Schmidt" out of elements. 3 | Lalalalalalalalalala 4 | La - La - La - La - La - La - La - La - La - La 5 | Lanthanum - Lanthanum - Lanthanum - Lanthanum - Lanthanum - Lanthanum - Lanthanum - Lanthanum - Lanthanum - Lanthanum 6 | Laboon 7 | La - B - O - O - N 8 | Lanthanum - Boron - Oxygen - Oxygen - Nitrogen 9 | Art Arterson 10 | Could not create name "Art Arterson" out of elements. 11 | Bob 12 | B - O - B 13 | Boron - Oxygen - Boron 14 | Coco Atas 15 | Co - Co - At - As 16 | Cobalt - Cobalt - Astatine - Arsenic 17 | Bob Bobber 18 | B - O - B - B - O - B - B - Er 19 | Boron - Oxygen - Boron - Boron - Oxygen - Boron - Boron - Erbium 20 | Bob Bobberson 21 | B - O - B - B - O - B - B - Er - S - O - N 22 | Boron - Oxygen - Boron - Boron - Oxygen - Boron - Boron - Erbium - Sulfur - Oxygen - Nitrogen 23 | Al Bobberson 24 | Al - B - O - B - B - Er - S - O - N 25 | Aluminum - Boron - Oxygen - Boron - Boron - Erbium - Sulfur - Oxygen - Nitrogen 26 | Al Allerson 27 | Could not create name "Al Allerson" out of elements. 28 | Al Allison 29 | Al - Al - Li - S - O - N 30 | Aluminum - Aluminum - Lithium - Sulfur - Oxygen - Nitrogen 31 | Allison Allisons 32 | Al - Li - S - O - N - Al - Li - S - O - N - S 33 | Aluminum - Lithium - Sulfur - Oxygen - Nitrogen - Aluminum - Lithium - Sulfur - Oxygen - Nitrogen - Sulfur 34 | Laboons 35 | La - B - O - O - N - S 36 | Lanthanum - Boron - Oxygen - Oxygen - Nitrogen - Sulfur 37 | Bo Bo 38 | B - O - B - O 39 | Boron - Oxygen - Boron - Oxygen 40 | Bo Bo Bo 41 | B - O - B - O - B - O 42 | Boron - Oxygen - Boron - Oxygen - Boron - Oxygen 43 | Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo BoBo Bo Bo Bo Bo Bo 44 | B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O - B - O 45 | Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen - Boron - Oxygen 46 | Bob Powers 47 | B - O - B - Po - W - Er - S 48 | Boron - Oxygen - Boron - Polonium - Tungsten - Erbium - Sulfur 49 | Tiny Powers 50 | Ti - N - Y - Po - W - Er - S 51 | Titanium - Nitrogen - Yttrium - Polonium - Tungsten - Erbium - Sulfur 52 | Pow Powerson 53 | Po - W - Po - W - Er - S - O - N 54 | Polonium - Tungsten - Polonium - Tungsten - Erbium - Sulfur - Oxygen - Nitrogen 55 | Nick Nickelback 56 | Could not create name "Nick Nickelback" out of elements. 57 | Nick Powers 58 | Ni - C - K - Po - W - Er - S 59 | Nickel - Carbon - Potassium - Polonium - Tungsten - Erbium - Sulfur 60 | Nick Atas 61 | Ni - C - K - At - As 62 | Nickel - Carbon - Potassium - Astatine - Arsenic 63 | Tiny Nick 64 | Ti - N - Y - Ni - C - K 65 | Titanium - Nitrogen - Yttrium - Nickel - Carbon - Potassium 66 | Bob Creat 67 | B - O - B - C - Re - At 68 | Boron - Oxygen - Boron - Carbon - Rhenium - Astatine 69 | Loopy Creat 70 | Could not create name "Loopy Creat" out of elements. 71 | Tsar Bomba 72 | Could not create name "Tsar Bomba" out of elements. 73 | Tsar Boo 74 | Ts - Ar - B - O - O 75 | Tennessine - Argon - Boron - Oxygen - Oxygen 76 | Tsar Tsar 77 | Ts - Ar - Ts - Ar 78 | Tennessine - Argon - Tennessine - Argon 79 | -------------------------------------------------------------------------------- /deliverables/4/answers2.txt: -------------------------------------------------------------------------------- 1 | Uncle Fermium 2 | Could not create name "Uncle Fermium" out of elements. 3 | Pink Pan 4 | P - In - K - Pa - N 5 | Phosphorus - Indium - Potassium - Protactinium - Nitrogen 6 | Barbara Kitchen 7 | B - Ar - Ba - Ra - K - I - Tc - He - N 8 | Boron - Argon - Barium - Radium - Potassium - Iodine - Technetium - Helium - Nitrogen 9 | Lulu Laker 10 | Lu - Lu - La - K - Er 11 | Lutetium - Lutetium - Lanthanum - Potassium - Erbium 12 | Calvin&&&&& 13 | Ca - Lv - In 14 | Calcium - Livermorium - Indium 15 | Geoff Kryptonite 16 | Ge - O - F - F - Kr - Y - Pt - O - Ni - Te 17 | Germanium - Oxygen - Fluorine - Fluorine - Krypton - Yttrium - Platinum - Oxygen - Nickel - Tellurium 18 | Gabby Penguin 19 | Could not create name "Gabby Penguin" out of elements. 20 | Sassy Nicholas 21 | S - As - S - Y - Ni - C - Ho - La - S 22 | Sulfur - Arsenic - Sulfur - Yttrium - Nickel - Carbon - Holmium - Lanthanum - Sulfur 23 | Kris Fedshin 24 | Kr - I - S - Fe - Ds - H - In 25 | Krypton - Iodine - Sulfur - Iron - Darmstadtium - Hydrogen - Indium 26 | Nick Fire 27 | Ni - C - K - F - I - Re 28 | Nickel - Carbon - Potassium - Fluorine - Iodine - Rhenium 29 | -------------------------------------------------------------------------------- /deliverables/4/deliverable4.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 3 | 4 | DUE 8 NOV 2017 5 | 6 | ## Deliverable 4 7 | 8 | In this deliverable, you and a partner will write software to determine whether or not a group of names listed in a file can be written as a grouping of element abbreviations. 9 | 10 | I have included a list of element names and their abbreviations in the file `elements.txt` in this directory. 11 | 12 | You may want to look into the concept of macros in your text editor to modify this list into something appropriate for whichever format you want to use. 13 | 14 | Under _no_ circumstances should the program crash or should the user see an exception or stack trace. You should handle all edge cases that might be thrown at you, such as a non-existent file, no arguments, etc. I will not enumerate all of these but several will be tested. 15 | 16 | The program shall accept one argument, which is the name of a file. Your program will read in each line of the file and attempt to convert that name to its element abbreviations. Spaces and any other non-alphabetic characters should be ignored. Your program will then write to standard output (i.e., `System.out.println(...)`) the abbreviations separated by " - "'s, and the element names beneath that. Empty lines in the file should be ignored. If you cannot make the name into elements, you should print "Could not create name *name* out of elements." where *name* is the name passed in. 17 | 18 | The program shall be case-insensitive. 19 | 20 | See sample_output.txt for samples. 21 | 22 | You should work on making this program execute as quickly as possible. You may use all computing resources available to you. This will be run on a four-core system with eight gigabytes of RAM. No other programs will be running at the time. 23 | 24 | Your program will be timed using the sample_input.txt text file. Make sure that your code works with this. 25 | 26 | The fastest three programs in the class will receive bonus points. 27 | 28 | You should explain how your program has been sped up in your summary. You should do at least one modification to speed it up after initial input. 29 | 30 | ## Format 31 | Every assignment should have a title page with: 32 | * The name of the students in the group 33 | * The title "CS 1632 - DELIVERABLE 4: Performance Testing Using VisualVM" 34 | 35 | There is no need to print out the code. It should be available on GitHub or a similar code-sharing site BY THE BEGINNING OF CLASS. 36 | 37 | In order to determine the "hot spots" of the application, you will need to run a profiler such as VisualVM (download at https://visualvm.github.io/). Using a profiler, determine what code/methods/objects you can modify to speed up the execution time of this program. 38 | 39 | For the summary, describe how you profiled the application and determined the methods to refactor, and why you changed what you did. The summary should not be more than a few paragraphs - definitely less than a page. 40 | 41 | After this, include a screenshots of VisualVM (or another profiler, if you use that) profiling your code. 42 | 43 | There should be at least twelve unit tests. These should be run with a TestRunner just like in D2 and D3. 44 | 45 | You should time program with the sample file three times AND indicate the mean and median amount of time it took to execute. You can do this with the `time` command in Unix-like systems (Linux, OS X, BSD) or the `Measure-Command` command in PowerShell on Windows systems. 46 | 47 | ## Grading 48 | * Summary - 10% 49 | * VisualVM (or other profiler) screenshots - 10% 50 | * Final times (>= 3 of each + mean) included - 10% 51 | * Code and Execution Speed - 50% 52 | * Unit Tests - 20% 53 | 54 | -------------------------------------------------------------------------------- /deliverables/4/elements.txt: -------------------------------------------------------------------------------- 1 | "Ac": "Actinium", 2 | "Ag": "Silver", 3 | "Al": "Aluminum", 4 | "Am": "Americium", 5 | "Ar": "Argon", 6 | "As": "Arsenic", 7 | "At": "Astatine", 8 | "Au": "Gold", 9 | "B": "Boron", 10 | "Ba": "Barium", 11 | "Be": "Beryllium", 12 | "Bh": "Bohrium", 13 | "Bi": "Bismuth", 14 | "Bk": "Berkelium", 15 | "Br": "Bromine", 16 | "C": "Carbon", 17 | "Ca": "Calcium", 18 | "Cd": "Cadmium", 19 | "Ce": "Cerium", 20 | "Cf": "Californium", 21 | "Cl": "Chlorine", 22 | "Cm": "Curium", 23 | "Cn": "Copernicium", 24 | "Co": "Cobalt", 25 | "Cr": "Chromium", 26 | "Cs": "Cesium", 27 | "Cu": "Copper", 28 | "Db": "Dubnium", 29 | "Ds": "Darmstadtium", 30 | "Dy": "Dysprosium", 31 | "Er": "Erbium", 32 | "Es": "Einsteinium", 33 | "Eu": "Europium", 34 | "F": "Fluorine", 35 | "Fe": "Iron", 36 | "Fl": "Flerovium", 37 | "Fm": "Fermium", 38 | "Fr": "Francium", 39 | "Ga": "Gallium", 40 | "Gd": "Gadolinium", 41 | "Ge": "Germanium", 42 | "H": "Hydrogen", 43 | "He": "Helium", 44 | "Hf": "Hafnium", 45 | "Hg": "Mercury", 46 | "Ho": "Holmium", 47 | "Hs": "Hassium", 48 | "I": "Iodine", 49 | "In": "Indium", 50 | "Ir": "Iridium", 51 | "K": "Potassium", 52 | "Kr": "Krypton", 53 | "La": "Lanthanum", 54 | "Li": "Lithium", 55 | "Lr": "Lawrencium", 56 | "Lu": "Lutetium", 57 | "Lv": "Livermorium", 58 | "Mc": "Moscovium", 59 | "Md": "Mendelevium", 60 | "Mg": "Magnesium", 61 | "Mn": "Manganese", 62 | "Mo": "Molybdenum", 63 | "Mt": "Meitnerium", 64 | "N": "Nitrogen", 65 | "Na": "Sodium", 66 | "Nb": "Niobium", 67 | "Nd": "Neodymium", 68 | "Ne": "Neon", 69 | "Nh": "Nihonium", 70 | "Ni": "Nickel", 71 | "No": "Nobelium", 72 | "Np": "Neptunium", 73 | "O": "Oxygen", 74 | "Og": "Oganesson", 75 | "Os": "Osmium", 76 | "P": "Phosphorus", 77 | "Pa": "Protactinium", 78 | "Pb": "Lead", 79 | "Pd": "Palladium", 80 | "Pm": "Promethium", 81 | "Po": "Polonium", 82 | "Pr": "Praseodymium", 83 | "Pt": "Platinum", 84 | "Pu": "Plutonium", 85 | "Ra": "Radium", 86 | "Rb": "Rubidium", 87 | "Re": "Rhenium", 88 | "Rf": "Rutherfordium", 89 | "Rg": "Roentgenium", 90 | "Rh": "Rhodium", 91 | "Rn": "Radon", 92 | "Ru": "Ruthenium", 93 | "S": "Sulfur", 94 | "Sb": "Antimony", 95 | "Sc": "Scandium", 96 | "Se": "Selenium", 97 | "Sg": "Seaborgium", 98 | "Si": "Silicon", 99 | "Sm": "Samarium", 100 | "Sn": "Tin", 101 | "Sr": "Strontium", 102 | "Ta": "Tantalum", 103 | "Tb": "Terbium", 104 | "Tc": "Technetium", 105 | "Te": "Tellurium", 106 | "Th": "Thorium", 107 | "Ti": "Titanium", 108 | "Tl": "Thallium", 109 | "Tm": "Thulium", 110 | "Ts": "Tennessine", 111 | "U": "Uranium", 112 | "V": "Vanadium", 113 | "W": "Tungsten", 114 | "Xe": "Xenon", 115 | "Y": "Yttrium", 116 | "Yb": "Ytterbium", 117 | "Zn": "Zinc", 118 | "Zr": "Zirconium" 119 | -------------------------------------------------------------------------------- /deliverables/4/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Summary: _____ / 10 2 | * Specify any issues had by student (-4 if not) 3 | * More than one typo, -1 per each (up to -3) 4 | 5 | VisualVM Screenshot: _____ / 10 6 | 7 | Final times (>3 of each + mean): _____ / 10 8 | 9 | Code and Execution speed : _____ / 50 10 | * Error message if <1 or >1 argument (-5 if not) 11 | * Error message if file does not exist (-5 if not) 12 | * Ignores non-alpabetic characters (-5 if not) 13 | * Processes sample_input.txt correctly (-4 per issue) 14 | * Processes sample_input2.txt correctly (-4 per issue) 15 | 16 | JUnit tests (20%): 17 | 18 | Tests compile and pass: _____ / 2 19 | * Tests are well-commented (-2 each if not) 20 | * Tests have proper assertions (-4 each if not) 21 | * Tests good mix of base and edge cases (up to -5) 22 | * At least 12 (-5 per each unit test under 12, up to -20) 23 | 24 | Submission issues (-10) or other adjustments: _____ 25 | 26 | Total: _____ / 100 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /deliverables/4/sample_input.txt: -------------------------------------------------------------------------------- 1 | John Jacob Jingleheimer Schmidt 2 | Lalalalalalalalalala 3 | Laboon 4 | Art Arterson 5 | Bob 6 | Coco Atas 7 | Bob Bobber 8 | Bob Bobberson 9 | Al Bobberson 10 | Al Allerson 11 | Al Allison 12 | Allison Allisons 13 | Laboons 14 | Bo Bo 15 | Bo Bo Bo 16 | Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo Bo 17 | Bob Powers 18 | Tiny Powers 19 | Pow Powerson 20 | Nick Nickelback 21 | Nick Powers 22 | Nick Atas 23 | Tiny Nick 24 | Bob Creat 25 | Loopy Creat 26 | Tsar Bomba 27 | Tsar Boo 28 | Tsar Tsar 29 | -------------------------------------------------------------------------------- /deliverables/4/sample_input2.txt: -------------------------------------------------------------------------------- 1 | Uncle Fermium 2 | Pink Pan 3 | Barbara Kitchen 4 | Lulu Laker 5 | Calvin&&&&& 6 | Geoff Kryptonite 7 | Gabby Penguin 8 | Sassy Nicholas 9 | Kris Fedshin 10 | Nick Fire 11 | 12 | -------------------------------------------------------------------------------- /deliverables/4/sample_output.txt: -------------------------------------------------------------------------------- 1 | $ echo "Note: cat displays the file" 2 | Note: cat displays the file 3 | 4 | $ cat tsars.txt 5 | Tsar Meow 6 | Tsar Ra 7 | Tsar Nicholas 8 | 9 | $ java Element tsars.txt 10 | Could not create name "Tsar Meow" out of elements. 11 | Ts - Ar - Ra 12 | Tennessine - Argon - Radium 13 | Ts - Ar - Ni - C - Ho - La - S 14 | Tennessine - Argon - Nickel - Carbon - Holmium - Lanthanum - Sulfur 15 | 16 | $ cat fds 17 | cat: fds: No such file or directory 18 | 19 | $ java Element fds 20 | Error: File "fds" does not exist. 21 | 22 | $ java Element tsars.txt boo.txt 23 | Error: Enter only one argument, the file to read. 24 | 25 | $ echo "Note: noogie.txt has blank lines in it. These are ignored." 26 | Note: noogie.txt has blank lines in it. These are ignored. 27 | 28 | $ cat noogie.txt 29 | 30 | Laboon 31 | 32 | Laboon 33 | 34 | Allison 35 | 36 | Boo 37 | 38 | Bill 39 | 40 | $ java Element noogie.txt 41 | La - B - O - O - N 42 | Lanthanum - Boron - Oxygen - Oxygen - Nitrogen 43 | La - B - O - O - N 44 | Lanthanum - Boron - Oxygen - Oxygen - Nitrogen 45 | Al - Li - S - O - N 46 | Aluminum - Lithium - Sulfur - Oxygen - Nitrogen 47 | B - O - O 48 | Boron - Oxygen - Oxygen 49 | Could not create name "Bill" out of elements. 50 | 51 | $ cat lala.txt 52 | Lala Mc'Boo*& 53 | La&&&La&&&Ra 54 | 55 | $ java Element lala.txt 56 | La - La - Mc - B - O - O 57 | Lanthanum - Lanthanum - Moscovium - Boron - Oxygen - Oxygen 58 | La - La - Ra 59 | Lanthanum - Lanthanum - Radium 60 | -------------------------------------------------------------------------------- /deliverables/5/checkstyle-7.0-all.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/deliverables/5/checkstyle-7.0-all.jar -------------------------------------------------------------------------------- /deliverables/5/deliverable5.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 3 | 4 | DUE 20 NOV 2017 5 | 6 | ## Deliverable 5 7 | 8 | For this assignment, you and a partner will use static analysis as part of developing a pairwise test generator. 9 | 10 | This project will consist of the following steps: 11 | 12 | 1. Write a program which accepts a list of arguments, then uses the naive pairwise test generation algorithm discussed in class to determine a pairwise test plan 13 | 1. Use findbugs and checkstyle to statically analyze your code 14 | 2. Use checkstyle with the included configuration file (google_checks_modified.xml) to find any style issues with your code 15 | 3. Fix *all* of the errors found by findbugs (with the exception of "Dead store to local variables" issues) and checkstyle 16 | 17 | Your final version should have no bugs found by findbugs (except for dead local stores) and no violations reported by checkstyle. 18 | 19 | You and your partner should have tests for all of your methods except for `public static void main()`. There should be at a bare minimum twelve unit tests checking for both edge cases and happy path cases. You do not need to use stubs/mocks/doubles/fakes if you prefer not to do so. 20 | 21 | Your code should be well-written and separated into appropriate methods and/or classes. 22 | 23 | The specific requirements for the program are listed in the file `requirements.md` in this directory. 24 | 25 | The checkstyle jar file is also in this directory. Checkstyle is a static analysis tool which acts as a linter - that is, it will tell you if there are style issues with your code which would not ordinarily impact compilation and execution, but may indicate errors, poor commenting, style violations, or simply difficult-to-read code. 26 | 27 | We are using a modified Google style guide (also included in this directory). 28 | 29 | You may want to run checkstyle on a previous piece of code (I recommend deliverable 4!) that you have written to see what kinds of issues it will find (and which ones you are likely to make). 30 | 31 | You will also use findbugs, as described in class, to find possible bugs in your code and fix them. FindBugs is available here: http://findbugs.sourceforge.net/ 32 | 33 | Note that findbugs has a known issue with the "Dead store to local variable" analysis. You may ignore any errors of this kind (you can filter them out or just mentally ignore them). 34 | 35 | Run checkstyle using the included google_checks_modified.xml configuration file on all of your code. Fix all of the issues so that the style is in line with the modified Google code guidelines (these are actual Google Java style guidelines, btw, with some small modifications by yours truly). Before turning this in, your checkstyle run should show _no_ issues. 36 | 37 | Checkstyle Usage Example: 38 | ``` 39 | java -jar ~/checkstyle/checkstyle-7.0-all.jar -c ./google_checks_modified.xml ~/pitt/CS1632/*.java 40 | ``` 41 | 42 | For the summary, include a listing of the issues you found with your code. This should not be more than a few paragraphs. 43 | 44 | Include screenshots of both the FINAL findbugs and checkstyle output (should have no errors for either). 45 | 46 | ## Format 47 | Every assignment should have a title page with: 48 | * The name of the students in the group and their GitHub usernames 49 | * The title "CS 1632 - DELIVERABLE 5: Static Analysis" 50 | * The URL for your git repository 51 | 52 | There is no need to print out the code, only the deliverable paperwork. It should be available on GitHub or a similar code-sharing site BY THE BEGINNING OF CLASS. 53 | 54 | ## Grading 55 | * Summary - 5% 56 | * Screenshots of Findbugs and checkstyle output - 5% 57 | * Functionality (including handling bad input!) - 25% 58 | * All issues from checkstyle fixed - 20% 59 | * All issues from FindBugs fixed - 20% 60 | * Unit tests (all should pass): 25% 61 | 62 | Please feel free to email me or come to office hours to discuss any problems you have. 63 | 64 | -------------------------------------------------------------------------------- /deliverables/5/google_checks_modified.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 67 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 92 | 93 | 94 | 96 | 97 | 98 | 99 | 101 | 102 | 103 | 104 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 116 | 117 | 118 | 119 | 121 | 123 | 125 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /deliverables/5/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | Summary: ____ / 5 2 | * -4 if no issues/details given 3 | * -3 if > 1 grammatical error 4 | 5 | * Screenshots of Findbugs and checkstyle output ____ / 5 6 | * -3 if only one or the other 7 | 8 | * Functionality (25%): ____ / 25 9 | * If code does not compile, 0/25 on this section 10 | * -5 if it does handle no command-line args 11 | * -5 if appropriate message not shown for 1 arg 12 | * -10 if it does not show truth table for 2 args 13 | * -10 if does not show valid covering array for 3 args 14 | * -10 if does not show valid covering array for 4 args 15 | * -5 if "true" is not shown as 1, "false" as 0 16 | * -5 if program name is not "Pairwise" 17 | 18 | * Unit tests (25%): ____ / 25 19 | * If tests do not compile, 0/25 on this section 20 | * -4 for each test not commented 21 | * -4 if test commented, but comments are wrong 22 | * -5 for each test with no assertion 23 | * -5 for each method (besides main) not tested 24 | * If <12 tests, -5 for each number below 12 25 | * -5 for "invalid" tests (e.g., tests which always pass) 26 | * -4 for each test that fails 27 | 28 | All checkstyle issues fixed: ____ / 20 29 | * -5 for each error still found 30 | * -3 if documented but not fixed 31 | 32 | All FindBugs issues fixed ____ / 20 33 | * -7 for every issue FindBugs still finds 34 | * -5 if found, but documented why not fixed 35 | * EXCEPT Dead Local Store, ignore those 36 | 37 | TOTAL: ____ / 100 38 | -------------------------------------------------------------------------------- /deliverables/5/requirements.md: -------------------------------------------------------------------------------- 1 | FUN-INPUT: The system shall accept a list of two or more parameters from the command line, each of which will correspond to one parameter in the covering array. 2 | 3 | FUN-TRUNCATE: If a parameter is more than ten characters, it should be truncated to ten characters. 4 | 5 | FUN-PARAM-TYPES: All parameters will be treated as Boolean values. There will be no other kinds of parameters accepted. 6 | 7 | FUN-ALGORITHM: The system shall use the naive pairwise test generation algorithm as discussed in class. It shall not use IPOG or any other algorithm for this purpose. 8 | 9 | FUN-BOOL-OUTPUT: The system shall output all "true" values as "1" and all false values as "0". These shall be displayed directly underneath their corresponding parameter name. 10 | 11 | FUN-COVERING-ARRAY: The system shall output a covering array showing which tests could be executed to ensure that all pair possibilities (true/true, true/false, false/true, false/false) for any combination of two parameters. 12 | 13 | FUN-NO-EXHAUSTIVE: Barring the case of two parameters, which must show an exhaustive test plan, the system shall never show an array which indicates that an exhaustive test plan must be run. 14 | 15 | FUN-INVALID-INPUT: If there are zero or one parameters given as input to the program, it shall output the message "Please enter at least two parameters!" and exit. 16 | 17 | FUN-PROG-NAME: The name of the program shall be "Pairwise" and, after compilation, it shall be executable from the command line by typing "java Pairwise" along with any parameters. 18 | 19 | FUN-UNSPECIFIED: In the case of ambiguity or unspecified behavior in the requirements, the example output below shall be considered the correct behavior. 20 | 21 | ## Example Output 22 | 23 | NOTE: Your output does not need to exactly match the output here! There are numerous ways of creating a covering array. You may find that you have more or fewer rows than I do. This is perfectly fine as long as it is a valid covering array, generated by the naive algorithm discussed in class, and is not simply an exhaustive test (generic truth table). 24 | 25 | ``` 26 | $ java Pairwise 27 | Please enter at least two parameters! 28 | 29 | $ java Pairwise dog 30 | Please enter at least two parameters! 31 | 32 | $ java Pairwise dog cat 33 | dog cat 34 | 1 1 35 | 1 0 36 | 0 1 37 | 0 0 38 | 39 | $ java Pairwise dog cat bird 40 | dog cat bird 41 | 0 0 0 42 | 0 0 1 43 | 0 1 0 44 | 0 1 1 45 | 1 0 0 46 | 1 1 1 47 | 48 | $ java Pairwise dog cat bird lizard 49 | dog cat bird lizard 50 | 1 1 0 0 51 | 1 0 1 1 52 | 0 1 1 0 53 | 0 0 0 1 54 | 0 1 0 1 55 | 1 0 0 0 56 | 57 | ``` -------------------------------------------------------------------------------- /deliverables/6/deliverable6.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 3 | 4 | DUE 6 DEC 2017 5 | 6 | ## Deliverable 6 7 | 8 | For this final deliverable, you and a partner will develop a project from scratch (see details) below, along with a detailed report on the testing strategy used. 9 | 10 | Expect no mercy from my testing! This is a relatively simple program but you will be expected to deal with all edge cases, find defects ahead of time, think of performance issues as explained in the requirements, etc. I expect as close to bullet-proof an application as one could be expected to deliver, and that you have proved this by creating a good testing strategy based on all that we have learned this term. 11 | 12 | You will develop an entire testing strategy for the application. This testing strategy should cover all aspects of testing that we have covered. It should show that you have thought deeply about the particular concerns of this piece of software. 13 | 14 | I expect you to do independent research to determine general information about how to develop this application. You may also wish to review the syllabus to see all of the kinds of testing that we have discussed this semester and when they are relevant. 15 | 16 | Your paper should include the following three sections. You should LABEL each section clearly. You may use graphs, charts, etc. if these would help in understanding your position. 17 | 18 | You are not _required_ to create a traceability matrix for this assignment, but it would be a good addition to ensure that you have verified all of the requirements. 19 | 20 | 1. A review of the program's overall quality. This should be done using the Red-Yellow-Green template. It is up to you to determine the subsets of functionality and/or subsystems. 21 | 2. Areas of concern. We want the program to compare favorably in terms of features and quality with similar software. If there are known defects, list them here. These should be written using the standard defect template. It is much better for your grade if you find a defect yourself and report it than if I find it. 22 | 3. Testing strategies used. You should answer the following questions. 23 | 1. What kinds of tests did you write? Why? 24 | 2. What percentage of time/effort was allocated to each kind of test? 25 | 5. What recommendations would you give to help increase quality? 26 | 6. What parts of the code need to be cleaned up? 27 | 7. What kinds of things did you discover in exploratory testing? 28 | 8. If you developed a manual testing plan, include it here. 29 | 30 | ## Program Functionality 31 | 32 | You are going to develop an interpreter for a simple language, RPN++. This allows user to calculate using Reverse Polish Notation. It also supports simple output via the PRINT keyword, variables, and the ability to quit. 33 | 34 | Running the program without a filename will cause the program to enter a read-eval-print-loop (REPL). In REPL mode, users can enter expressions one line at a time. REPLs are widely used in many programming languages such as Ruby, Clojure, and Lisp. 35 | 36 | When running the program with one or more arguments, each argument shall be considered a path to a filename. The program shall execute each program stored in that filename. 37 | 38 | Detailed requirements are listed below. 39 | 40 | ## Requirements 41 | 42 | 1. The program shall be named RPN and should be runnable from the command line using the command "java RPN". 43 | 1. Tokens shall be numbers, variable names, operators, or one of the keywords QUIT, LET, or PRINT. 44 | 1. A number shall consist of one or more digits. All numbers shall be arbitrary-precision (i.e., there shall be no integer overflow - 999999999999999999999999999 shall be considered a valid number and stored as such). 45 | 1. Variable names can be a single letter (A-Z) and are case-insensitive (e.g., `a` and `A` refer to the same variable). 46 | 1. Operators can be +, -, /, or *, for add, subtract, divide, and multiply, respectively. 47 | 1. The keyword QUIT causes the program to end. 48 | 1. Any lines or tokens after the QUIT keyword are ignored. 49 | 1. The keyword LET is followed by a single-letter variable, then an RPN expression. The RPN expression is evaluated and the value of the variable is set to it. 50 | 1. The keyword PRINT is followed by an expression, and the interpreter shall print the result of that expression to standard output (stdout). 51 | 1. Keywords shall be case-insensitive (e.g. `print`, `PRINT`, or `pRiNt` are interchangeable) 52 | 1. Keywords shall only start a line (e.g., you cannot have a line such as "1 2 + PRINT 3") 53 | 1. Variables shall be considered initialized once they have been LET. It shall be impossible to declare a variable without initializing it to some value. 54 | 1. Referring to a variable which has not previously been LET (i.e. has not been declared) shall result in the program informing the user that the variable is uninitialized and QUIT the program with error code 1. It should inform the user in the following format: "Line n: Variable x is not initialized." where `x` is the name of the variable and `n` is the line number of the file the error occurred in. 55 | 1. The exception to the previous requirement is that if this occurs in REPL mode, the user shall be informed, but the line will simply be ignored. 56 | 1. If the stack for a given line is empty OR does not contain the correct number of elements on the stack for that operator, and an operator is applied, the program shall inform the user and QUIT the program with error code 2. It should inform the user in the following format: "Line n: Operator o applied to empty stack" where `o` is the operator used and `n` is the line number the error occurred in. 57 | 1. The exception to the previous requirement is that if this occurs in REPL mode, the user shall be informed, but the line will simply be ignored. 58 | 1. If the stack for a given line contains more than one element and the line has been evaluated, the program shall inform the user and QUIT the program with error code 3. It should inform the user in the following format: "Line n: y elements in stack after evaluation" where `y` is the number of elements in the stack and `n` is the line number the error occurred in. 59 | 1. The exception to the previous requirement is that if this occurs in REPL mode, the user shall be informed, but the line will simply be ignored. 60 | 1. If an expression used for initializing a LET variable is invalid, the variable is considered to have not been initialized. For example, "LET A 1 2" is invalid, and A is not initialized. 61 | 1. If an invalid keyword is used, the program shall inform the user and QUIT the program with error code 4. It should inform the user in the following format: "Line n: Unknown keyword k" where `k` is the keyword and `n` is the line number the error occurred in. 62 | 1. The exception to the previous requirement is that if this occurs in REPL mode, the user shall be informed, but the line will simply be ignored. 63 | 1. All other errors shall result in the program informing the user of the error and exiting with error code 5. At no point shall the end user of the system see a Java exception or stack trace. 64 | 1. All errors shall be written to standard error (stderr), not standard output (stdout). 65 | 1. In REPL mode, the result of each line shall be displayed immediately afterwards before another prompt comes up. 66 | 1. In REPL mode, PRINT shall not perform any additional work, as the result of the RPN expression evaluation will already be displayed. 67 | 1. In REPL mode, when displaying error messages, the current line shall be considered as the nth command entered. For example, the first line entered shall be considered Line 1, the second line entered Line 2, etc. 68 | 1. This program shall minimize real execution time, even at the expense of memory or CPU usage. 69 | 1. The ">" character shall be used as the prompt for REPL mode. 70 | 1. In case of ambiguity, the sample output shall be considered the ground truth. 71 | 1. When reading multiple files, all of the files shall be concatenated into one large file before processing. For example, when executing file1.rpn and file2.rpn, and file1.rpn initializes a variable A, file2.rpn can use variable A without initializing it. Similarly, if a QUIT is encountered at the end of file1.rpn, the entire program will quit and no lines in file2.rpn shall be executed. 72 | 1. Blank lines in files shall be ignored. 73 | 1. Lines in files are considered to be 1-indexed, that is, the first line in a file is line number 1, not 0. 74 | 1. Variable values shall not be persisted across executions. In other words, if I initialize a variable `a`, then quit the program and start it again, variable `a` is no longer initialized. 75 | 1. Tokens shall be separated by whitespace. 76 | 1. For concatenated files, the line number shall continue to increment for each line of the file. It shall not reset after a new file has been reached. 77 | 78 | ## Sample Output 79 | 80 | Simple runs 81 | 82 | ``` 83 | $ java RPN 84 | > 4 3 + 85 | 7 86 | > LET a 10 87 | 10 88 | > a 1 + 89 | 11 90 | > 2 91 | 2 92 | > LET b 2 2 + 93 | 4 94 | > LET c a b + 95 | 14 96 | > PRINT c 97 | 14 98 | > PRINT c 1 + 99 | 15 100 | > 10 10 * 5 5 * 0 0 * + + 101 | 125 102 | > QUIT 103 | 104 | $ 105 | ``` 106 | 107 | Errors 108 | 109 | ``` 110 | $ java RPN 111 | > a 4 + 112 | Line 1: Variable a is not initialized 113 | > 1 2 + + 114 | Line 2: Operator + applied to empty stack 115 | > 3 4 5 116 | Line 3: 3 elements in stack after evaluation 117 | > LOOP 118 | Line 4: Unknown keyword LOOP 119 | > 4 3 LET + a 120 | Line 5: Could not evaluate expression 121 | > LET a 122 | Line 6: Operator LET applied to empty stack 123 | > QUIT BUMBLEBEE 124 | 125 | $ echo Note BUMBLEBEE was ignored 126 | Note BUMBLEBEE was ignored 127 | ``` 128 | 129 | Big numbers 130 | 131 | ``` 132 | > 999999999999999999 999999999999999999 * 133 | 999999999999999998000000000000000001 134 | > LET a 0 999999999999999999999999999 - 135 | -999999999999999999999999999 136 | > LET b -1 137 | -1 138 | > a b + 139 | -1000000000000000000000000000 140 | > QUIT 141 | ``` 142 | 143 | Files 144 | 145 | ``` 146 | $ cat File1.rpn 147 | LET A 1 148 | LET B 2 149 | PRINT A B + 150 | 151 | $ java RPN File1.rpn 152 | 3 153 | 154 | $ cat File2.rpn 155 | PRINT -1 1 + 156 | PRINT 0 157 | PRINT 100 0 * 158 | QUIT 159 | 160 | $ java RPN File2.rpn 161 | 0 162 | 0 163 | 0 164 | 165 | $ java RPN File1.rpn File2.rpn 166 | 3 167 | 0 168 | 0 169 | 0 170 | 171 | $ java RPN File2.rpn File1.rpn 172 | 0 173 | 0 174 | 0 175 | 176 | $ echo Note that the QUIT keyword in File2 made File1 not run 177 | Note that the QUIT keyword in File2 made File1 not run 178 | ``` 179 | 180 | Errors in files 181 | 182 | ``` 183 | $ cat Bad.rpn 184 | LET A 1 185 | LET B 2 186 | PRINT 1 2 3 187 | PRINT B 188 | PRINT C 189 | 190 | $ java RPN Bad.rpn 191 | Line 3: 3 elements in stack after evaluation 192 | 193 | $ cat Bad2.rpn 194 | QUOMBLE 195 | 1 2 + 196 | 3 4 - 197 | 198 | $ java RPN Bad2.rpn 199 | Line 1: Unknown keyword QUOMBLE 200 | 201 | $ cat Bad3.rpn 202 | LET a 100 100 + 203 | LET b 60 + 204 | LET c a b + 205 | PRINT c 206 | 207 | $ java RPN Bad3.rpn 208 | Line 2: Operator + applied to empty stack 209 | 210 | $ cat Bad4.rpn 211 | PRINT 1 212 | LET a 100 100 + 213 | LET b 60 + 214 | LET c a b + 215 | PRINT c 216 | 217 | $ java RPN Bad4.rpn 218 | 1 219 | Line 3: Operator + applied to empty stack 220 | ``` 221 | 222 | ## Format 223 | Every assignment should have a title page with: 224 | * The name of the students in the group 225 | * The title "CS 1632 - DELIVERABLE 6: Testing Strategy for RPN++" 226 | 227 | ## Automated Test Suite 228 | 229 | I expect a unit test suite of at least 20 unit tests, evaluating a variety of different base, edge, and possibly corner cases. As always, this should be well-commented and of high quality. 230 | 231 | ## Grading 232 | ``` 233 | Overall review of quality: 10% 234 | Description of issues and enhancements: 10% 235 | Description of testing strategy: 20% 236 | Program Functionality: 50% 237 | Automated Test Suite: 20% 238 | ``` 239 | 240 | Please feel free to email me or come to office hours to discuss any problems you have. 241 | 242 | -------------------------------------------------------------------------------- /deliverables/6/file1.rpn: -------------------------------------------------------------------------------- 1 | LET a 10 10 10 + + 2 | LET b 4 4 4 - - 3 | LET c a b + 4 | print a 5 | print b 6 | print c 7 | 4 5 + 8 | 6 3 / 9 | print a 10 | print b 11 | print c 12 | -------------------------------------------------------------------------------- /deliverables/6/file2.rpn: -------------------------------------------------------------------------------- 1 | 9 8 * 2 | 6 7 * 3 | print 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 * * * * * * * * * * * * * * * * * * * * * * 4 | PRINT 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 * * * * * * * * * 5 | PRINT 1 -------------------------------------------------------------------------------- /deliverables/6/file3.rpn: -------------------------------------------------------------------------------- 1 | LET A 0 0 + 2 | LET a 1 3 + 3 | print A 4 | QUIT 5 | LET b 4 4 + 6 | print b 7 | -------------------------------------------------------------------------------- /deliverables/6/file4.rpn: -------------------------------------------------------------------------------- 1 | let a -9 2 | let b -9 3 | let α 0 -------------------------------------------------------------------------------- /deliverables/6/file5.rpn: -------------------------------------------------------------------------------- 1 | let p 17 17 17 + - 2 | let o 3 | print p -------------------------------------------------------------------------------- /deliverables/6/file6.rpn: -------------------------------------------------------------------------------- 1 | let i 7 7 7 * * 2 | let o i i i - - 3 | let u b -------------------------------------------------------------------------------- /deliverables/6/file7.rpn: -------------------------------------------------------------------------------- 1 | let i 7 7 7 * * 2 | let o i i i - - 3 | let u lol 4 | print i -------------------------------------------------------------------------------- /deliverables/6/grading_rubric.txt: -------------------------------------------------------------------------------- 1 | * Quality Review ____ / 10 2 | 3 | 4 | 5 | * Description of issues / enhancements ____ / 10 6 | 7 | 8 | 9 | * Description of testing strategy ____ / 10 10 | 11 | 12 | 13 | 14 | * Functionality : ____ / 50 15 | 16 | REPL: 17 | 18 | 19 | 20 | File1: 21 | 22 | 23 | 24 | File2: 25 | 26 | 27 | 28 | File3: 29 | 30 | 31 | 32 | File4: 33 | 34 | 35 | 36 | 37 | * Automated Test Suite: ____ / 20 38 | 39 | 40 | 41 | 42 | 43 | * Other issues/bonus: ____ / 0 44 | 45 | 46 | TOTAL: ____ / 100 47 | -------------------------------------------------------------------------------- /exercises/1/GoatGoatCar.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/1/GoatGoatCar.jar -------------------------------------------------------------------------------- /exercises/1/exercise1.md: -------------------------------------------------------------------------------- 1 | # CS 1632 - Software Quality Assurance 2 | Fall Semester 2017 - Exercise 1 3 | 4 | For this exercise, your group will determine a test plan for the simple simulator GoatGoatCar, based on the requirements listed. There are several known defects in the software; you will need to find and report on at least two. Additionally, a traceability matrix showing the mapping of test cases to requirements is required. 5 | 6 | There should be six (no more, no less) test cases altogether. 7 | 8 | Test cases should mention all necessary preconditions, execution steps, and postconditions. 9 | 10 | It is expected that you actually execute the test plan in order to find the defects, along with some exploratory testing to determine how the system works and where defects might lie. There are AT LEAST two defects. Full credit will be given only to those who properly find and describe at least two. While you are not expected to find *all* of the defects, a reasonable test plan should definitely find at least two. This is an intentionally target-rich environment. 11 | 12 | You should EMAIL me the completed test plan. This must be in to me by the next class, although I highly recommend you work on it in class. 13 | 14 | You may ask me any questions on writing a test plan during class. 15 | 16 | Remember the correct format for test cases - 17 | 18 | ``` 19 | IDENTIFIER: 20 | TEST CASE: 21 | PRECONDITIONS: 22 | EXECUTION STEPS: 23 | POSTCONDITIONS: 24 | ``` 25 | 26 | The IDENTIFIER is some value which will UNIQUELY specify the test case. It can be a number, word or any other mnemonic (e.g. TEST-INVALID-TIMES, TEST-LOW-NUM-TIMES, etc.). 27 | 28 | Remember the correct format for defects - 29 | 30 | ``` 31 | SUMMARY: 32 | DESCRIPTION: 33 | REPRODUCTION STEPS: 34 | EXPECTED BEHAVIOR: 35 | OBSERVED BEHAVIOR: 36 | ``` 37 | 38 | Other attributes of a defect (e.g., SEVERITY or IMPACT) are not necessary. The test case which found the defect should be listed as part of the DESCRIPTION. 39 | 40 | A traceability matrix shows allows us to determine that our test cases are checking requirements, and that our requirements have test coverage. See Chapter 6 section 6 (6.6) in the textbook for examples and detail on creating them. 41 | 42 | Note that some test cases may actually test several requirements. You should specify the one that the test case fits best - that is, what are you really trying to test with this test case? 43 | 44 | Note that it is NOT necessary for all requirements to be covered by this assignment! 45 | 46 | ## Grading 47 | 48 | ``` 49 | Test cases - 1.0 point 50 | Defects (2) - 0.7 points 51 | Traceability Matrix - 0.3 points 52 | Total: 2 points 53 | 54 | You may get partial credit for either part. 55 | ``` 56 | 57 | ## GoatGoatCar 58 | GoatGoatCar is going to be our way of determining the correct answer to the "Monty Hall Problem" (https://en.wikipedia.org/wiki/Monty_Hall_problem). The Monty Hall Problem can be summarized as follows: 59 | 60 | _Assume you are on a game show with three closed doors. Behind one door is a car (which you want), and behind the other two doors are goats (which you do not want - if you do want a goat, I implore you to research how difficult goat tending is). You pick one door, which you hope has the car behind it. The game show host - who knows where the car is, and so will not open that door - opens up one of the two doors you did not select. Behind that door is, of course, a goat._ 61 | 62 | _The question: is the optimal strategy to switch doors to the remaining closed door, to stay with the door you've already selected, or does it not matter?_ 63 | 64 | Our program will attempt to find the solution the worst possible way - by brute force. It will simulate a large number of these decisions and give a summary at the end of what percentage of the time switching would give you the "good item" and what percentage of the time staying would have won you the "bad" item. 65 | 66 | The program will accept four arguments, in this order: 67 | 68 | * __"Good" option__ - This will be the item that the player actually wants (e.g., a car). 69 | 70 | * __"Bad" option__ - This will be the item that the player does not want (e.g., a goat) 71 | 72 | * __Num Times__ - This is the number of rounds that will be simulated. 73 | 74 | * __Num Threads__ - This will be the number of threads that the simulation runs in 75 | 76 | Example command to execute. This will use "car" as the good choice, "goat" as the bad choice, 10001 as the number of rounds to simulate, and it will do it on four threads. 77 | 78 | ``` 79 | $ java -jar GoatGoatCar.jar car goat 10001 4 80 | ``` 81 | 82 | GoatGoatCar.jar is available in this directory. 83 | 84 | The requirements are listed in the file requirements.md in this directory. 85 | 86 | -------------------------------------------------------------------------------- /exercises/1/requirements.md: -------------------------------------------------------------------------------- 1 | FUN-BASIC-CALC - The system shall calculate the results of switching or staying, according to the defined Monty Hall problem, for "number of times" iterations. 2 | FUN-DISPLAY-RESULTS - After calculating, the system shall display this information to the user after calculating, using percentages with up to three places after the decimal, and then stop execution. This display shall print out the passed-in String versions of the "good" and "bad" options as defined in the arguments. 3 | 4 | FUN-ARGS-NUMBER - The system shall accept four arguments from the command line, in the following order: good option, bad option, number of times, number of threads. If there are fewer or more than four arguments, the system will display the usage information for the program and shut down.. 5 | 6 | FUN-ARGS-INVALID - If an argument is invalid for any reason (such as, the arguments for the number of times or number of threads cannot be parsed as a positive integer), then the system shall explain the reason that it cannot run and will shut down. At no point shall the system display a Java exception or stack trace directly to the user. 7 | 8 | FUN-SMALL-NUM - If the "number of times" argument is less than 100, the system shall issue a warning and ask the user if they wish to continue. 9 | -------------------------------------------------------------------------------- /exercises/2/LaboonCoin/LaboonCoin.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class LaboonCoin { 4 | 5 | public ArrayList blockchain = new ArrayList(); 6 | 7 | /** 8 | * Given a block's data, the previous hash, a nonce, and a final 9 | * hash which is the hash of the previous three data elements, 10 | * will generate a String. This String will contain all of the above 11 | * elements, with the hashes and nonce values displayed in 8-hexit 12 | * hexadecimal values. This means that values must be prefixed with 13 | * 0's to ensure that they are padded to eight characters. 14 | * Each data element is separated by a pipe (|). 15 | * Example: 16 | * Bill Gave Joe $10|00000000|001aa59c|000e854a 17 | * ^data ^prev ^nonce ^finalHash 18 | * @param data - Included block data 19 | * @param prevHash - The hash value of the previous block 20 | * @param nonce - the nonce value for this block 21 | * @param hash - the final hash value for this block 22 | * @return String - string representation of the block 23 | */ 24 | 25 | public String createBlock(String data, int prevHash, int nonce, int hash) { 26 | return data + "|" 27 | + String.format("%08x", prevHash) + "|" 28 | + String.format("%08x", nonce) + "|" 29 | + String.format("%08x", hash); 30 | 31 | } 32 | 33 | /** 34 | * Return the entire blockchain, separated by \n's 35 | * (carriage returns) as a String. 36 | * @return String - string format of the entire blockchain 37 | */ 38 | public String getBlockChain() { 39 | StringBuilder toReturn = new StringBuilder(); 40 | 41 | for (String block : blockchain) { 42 | toReturn.append(block); 43 | toReturn.append("\n"); 44 | } 45 | 46 | return toReturn.toString(); 47 | 48 | } 49 | 50 | /** 51 | * Given a data in String format, find its LaboonHash value. 52 | * Note LaboonHash is generally not a hashing algorithm you would 53 | * want to use in real life. 54 | * The LaboonHash algorithm is as follows: 55 | * 1. Convert a String into a sequence of characters 56 | * 2. Initialize a starting value, n, of 10000000 (10 million) 57 | * 3. For each character, multiply n by its ASCII (char) value 58 | * 4. After multiplication, add the value of the ASCII (char) value to n 59 | * 5. Return n 60 | * For example, the LaboonHash of "boo" is: 61 | * n = 10000000 62 | * n = (n * 98) + 98 // 98 = ASCII of 'b' 63 | * n = (n * 111) + 111 // 111 = ASCII of 'o' 64 | * n = (n * 111) + 111 // 111 = ASCII of 'o' 65 | * Final hash: 12074581219890 66 | * Or: 67 | * n = 1000000 68 | * n = (1000000 * 98) + 98 = 980000098 69 | * n = (980000098 * 111) + 111 = 108780010989 70 | * n = (108780010989 * 111) + 11 = 12074581219890 71 | * n = 12074581219890 72 | * However, this is held in a 32-bit signed int and so will wrap around! 73 | * Thus it will be 1428150834, or 0x551fda32. 74 | * Some other helpful examples for testing are below. 75 | * "bill" (no quotes) hashes to 0x53c4142c 76 | * "laboon" (no quotes) hashes to 0x4e4587d6 77 | * null or the empty string hash to 0x00989680 78 | * @param data - entire piece of data to hash 79 | * @return int - hash value using LaboonHash algorithm 80 | */ 81 | 82 | public int hash(String data) { 83 | // TODO - IMPLEMENT LABOONHASH 84 | return -1; 85 | } 86 | 87 | /** 88 | * Given a certain level of difficulty, check to see if a given hash 89 | * has that many 0's at its beginning, when expressed as a hex String. 90 | * For example, assume difficulty level is set to 3. 91 | * 0x098ab873 is NOT valid - it only has one 0 at the beginning 92 | * 0xab000000 is NOT valid - despite having six 0's, they are not at the 93 | * beginning 94 | * 0x000fd98a IS valid - it has three 0's at the beginning 95 | * 0x000000d4 IS valid - it has three 0's at the beginning, plus more 96 | * 97 | * @param difficulty - Difficulty level (number of 0's) 98 | * @param hash - hash value to check 99 | * @return boolean - true if hash is valid for a block, false otherwise 100 | */ 101 | 102 | public boolean validHash(int difficulty, int hash) { 103 | // TODO - CHECK FOR VALID HASHES 104 | return false; 105 | } 106 | 107 | /** 108 | * Given some data and the previous hash value, find a nonce that 109 | * will make the data + hex string version of the previous hash 110 | * equal to a hash value with a given number of 0's at its front. 111 | * The difficulty is the number of 0's necessary. Note that average 112 | * time to hash will increase by a factor of 16 for each additional 113 | * level of difficulty. 114 | * Note that if difficulty is set too high, a nonce may NEVER be found 115 | * since we are using ints which are finite. I recommend you leave 116 | * the difficulty setting at the default (3). 117 | * @param data - The data in the block 118 | * @param prevHash - The hash value of the previous block 119 | * @param difficulty - The number of 0's to consider a hash valid 120 | * @return int - A nonce which makes the block's hash valid 121 | */ 122 | 123 | public int mine(String data, int prevHash, int difficulty) { 124 | int nonce = 0; 125 | String toTry; 126 | int hashVal = 0; 127 | boolean foundNonce = false; 128 | while (!foundNonce) { 129 | toTry = String.format("%08x", prevHash) + String.format("%08x", nonce) + data; 130 | // Uncomment for debugging purposes 131 | // System.out.print("Trying: " + toTry + ".. "); 132 | 133 | hashVal = hash(toTry); 134 | System.out.println("hash: " + String.format("%08x", hashVal)); 135 | if (validHash(difficulty, hashVal)) { 136 | foundNonce = true; 137 | } else { 138 | nonce++; 139 | } 140 | if (nonce == -1) { 141 | System.err.println("Could not find nonce"); 142 | } 143 | } 144 | return nonce; 145 | } 146 | 147 | /** 148 | * Run the program. 149 | * Loop until the user types 'q' or "Q" to quit. 150 | * After entering the data, the 151 | * PrevHash for the first ("genesis") block is by default 0 (0x00000000). 152 | * Note that this is in fact a valid hash for any 153 | */ 154 | 155 | public void run(int difficulty) { 156 | Scanner sc = new Scanner(System.in); 157 | boolean keepRunning = true; 158 | int prevHash = 0; 159 | while (keepRunning) { 160 | System.out.print("Enter data > "); 161 | String data = sc.nextLine(); 162 | if (data.equalsIgnoreCase("q")) { 163 | System.out.println("Final Blockchain:"); 164 | System.out.println(getBlockChain()); 165 | keepRunning = false; 166 | } else { 167 | System.out.println("Hash (just data) = " + String.format("%08x", hash(data))); 168 | System.out.println("Mining.."); 169 | int nonce = mine(data, prevHash, difficulty); 170 | System.out.println("Found nonce " + String.format("%08x", nonce) + "!"); 171 | int finalHash = hash( 172 | String.format("%08x", prevHash) 173 | + String.format("%08x", nonce) 174 | + data); 175 | System.out.println("Final hash " + String.format("%08x", finalHash) + "!"); 176 | 177 | String newBlock = createBlock(data, prevHash, nonce, finalHash); 178 | 179 | prevHash = finalHash; 180 | 181 | blockchain.add(newBlock); 182 | } 183 | 184 | } 185 | } 186 | 187 | /** 188 | * Program entry point. 189 | * Creates a new LaboonCoin instance and runs it. 190 | * Accepts one command-line argument, the difficulty level 191 | * This corresponds to how many 0's must be at the beginning of a 192 | * hash for it to be valid and for the block to be mined. 193 | * If this cannot be read or parsed, it will default to a difficulty 194 | * of 3. 195 | * @param args[] - command line arguments 196 | */ 197 | 198 | public static void main(String[] args) { 199 | int difficulty = 3; 200 | try { 201 | difficulty = Integer.parseInt(args[0]); 202 | if (difficulty < 0) { 203 | System.out.println("Negative numbers not allowed, defaulting to dificulty = 3"); 204 | difficulty = 3; 205 | } 206 | } catch (ArrayIndexOutOfBoundsException oobex) { 207 | System.out.println("No argument detected, defaulting to difficulty = 3"); 208 | } catch (NumberFormatException nfex) { 209 | System.out.println("Could not parse argument, defaulting to difficulty = 3"); 210 | } 211 | LaboonCoin lc = new LaboonCoin(); 212 | lc.run(difficulty); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /exercises/2/LaboonCoin/LaboonCoinTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.*; 4 | 5 | public class LaboonCoinTest { 6 | 7 | // Re-usable LaboonCoin reference. 8 | LaboonCoin _l; 9 | 10 | // Create a new LaboonCoin instance before each test. 11 | @Before 12 | public void setup() { 13 | _l = new LaboonCoin(); 14 | } 15 | 16 | // Assert that creating a new LaboonCoin instance 17 | // does not return a null reference 18 | @Test 19 | public void testLaboonCoinExists() { 20 | assertNotNull(_l); 21 | } 22 | 23 | // Creating a block String with valid data should return 24 | // a valid block. This includes printing data out 25 | // normally, the previous hash and current hash as a hex 26 | // representations of themself, and the nonce in hex 27 | // repretentation. Values should be delimited by 28 | // pipes. 29 | @Test 30 | public void testCreateBlockValid() { 31 | int prevHash = 0x0; 32 | int nonce = 0x16f2; 33 | int hash = 0x545ac; 34 | String validBlock = _l.createBlock("kitten", prevHash, nonce, hash); 35 | assertEquals("kitten|00000000|000016f2|000545ac", validBlock); 36 | } 37 | 38 | // Trying to represent a blockchain which has no blocks 39 | // in it should just return an empty string. 40 | @Test 41 | public void testGetBlockChainNoElements() { 42 | // By default, _l.blockchain has no elements in it. 43 | // So we can just test it immediately. 44 | String blockChain = _l.getBlockChain(); 45 | assertEquals("", blockChain); 46 | } 47 | 48 | 49 | // Viewing the blockchain as a full string which has valid 50 | // elements should include all of the elements. Note that the 51 | // final element DOES have a trailing \n! 52 | @Test 53 | public void testGetBlockChainElements() { 54 | _l.blockchain.add("TESTBLOCK1|00000000|000010e9|000a3cd8"); 55 | _l.blockchain.add("TESTBLOCK2|000a3cd8|00002ca8|0008ff30"); 56 | _l.blockchain.add("TESTBLOCK3|0008ff30|00002171|0009f908"); 57 | String blockChain = _l.getBlockChain(); 58 | assertEquals("TESTBLOCK1|00000000|000010e9|000a3cd8\nTESTBLOCK2|000a3cd8|00002ca8|0008ff30\nTESTBLOCK3|0008ff30|00002171|0009f908\n", blockChain); 59 | } 60 | 61 | // TODO - PUT YOUR SIX TESTS HERE 62 | 63 | } 64 | -------------------------------------------------------------------------------- /exercises/2/LaboonCoin/TestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class TestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(LaboonCoinTest.class); 15 | 16 | // For all test classes added, loop through and use JUnit 17 | // to run them. 18 | 19 | for (Class c: classesToTest) { 20 | 21 | Result r = JUnitCore.runClasses(c); 22 | 23 | // Print out any failures for this class. 24 | 25 | for (Failure f : r.getFailures()) { 26 | System.out.println(f.toString()); 27 | } 28 | 29 | // If r is not successful, there was at least one 30 | // failure. Thus, set anyFailures to true - this 31 | // can never be set back to false (no amount of 32 | // successes will ever eclipse the fact that there 33 | // was at least one failure. 34 | 35 | if (!r.wasSuccessful()) { 36 | anyFailures = true; 37 | } 38 | 39 | } 40 | 41 | // After completion, notify user if all tests passed or any failed. 42 | 43 | if (anyFailures) { 44 | System.out.println("\n!!! - At least one failure, see above."); 45 | } else { 46 | System.out.println("\nALL TESTS PASSED"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /exercises/2/LaboonCoin/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/2/LaboonCoin/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /exercises/2/LaboonCoin/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/2/LaboonCoin/junit-4.12.jar -------------------------------------------------------------------------------- /exercises/2/exercise2.md: -------------------------------------------------------------------------------- 1 | # Exercise 2 - JUnit and LaboonCoin 2 | 3 | You have probably heard of Bitcoin or another cryptocurrency such as Ethereum, Litecoin, or Monero. Today we are going to make our own blockchain to create a very simple way of storing data and cryptographically verifying it. We will do so by filling in a template program, LaboonCoin, and write tests to ensure that your methods are doing what you expect them to be doing. 4 | 5 | Blockchains work by creating a "block" of data, and having computers "work" to provide a verification of that data. This work involves finding a particular "nonce" value which will make the hash value of the data have a specific format (in our case, having _n_ zeros as its first _n_ hexits). The data to be hashed also includes the previous hash, thus "linking" the two blocks. By doing this repeatedly, a series of cryptographically signed blocks are formed. These not only prove that the data is valid, but also that it was added to the blockchain at a certain time. 6 | 7 | Hashing gives you a specific, finite value for a larger sequence of values. It will allow us to compare data without looking at every single character. Let us imagine an extremely simple hash function, which only accepts capital letters, and returns a single value between 0 and 25 for that string. The function accepts a string (which consists only of capital letters), and converts each letter to an equivalent value based on its alphabetical location (e.g A = 1, B = 2, C = 3, ... Z = 26). We now add each value, and then take that final value, modulo 26. 8 | 9 | Let's walk through an example using the phrase "AVOCADOS". We start with a counter - call it n - at 0. A is equal to 1, so we add 1 to the counter. V is equal to 22, and so on. This can also be expressed as 1 + 22 + 15 + 3 + 1 + 4 + 15 + 19, or 80. Remember that we are mapping to a finite range of 0..25, though, so we take 80 % 26 = 2. The "hash" of the string is thus 2. Modifying any character would give a different hash. We can thus "prove" that the hash goes along with the data, or compare data by comparing hashes. Although in our case there is a 1 in 26 chance of a "hash collision" (different data leading to the same hash), by increasing the size of the hash value, we can minimize that risk. We will be using Java int values as the hash (thus 32-bit values, not 0..25). Cryptographically secure hashes tend to be 256 bits or larger. 10 | 11 | Now we want to ensure that the block we are creating has been created immediately AFTER the previous block. We will then hash the previous block's hash value as part of our data string to prove that it comes right after it. 12 | 13 | However, this does not prove that much work has been done! Calculating a hash value, even a cryptographically useful one (such as SHA256, the hash function used in Bitcoin - see http://www.xorbin.com/tools/sha256-hash-calculator), takes a minuscule fraction of a second on a modern computer. However, trying to come up with a specific hash is very difficult and will require many attempts! 14 | 15 | This is where the "nonce" value comes in. This is a value added to the block, and hashed with it (along with the data and previous hash) to try and make a hash value with specific properties. In our case, we are going to try to have our hash generate values with leading 0's. We will have to try many, many nonce values to find a hash which meets these criteria! Once we do, though, we have found what is called "the golden nonce" and get a reward of bitcoin from the network. If someone else finds it before us, we start over again. This is called "mining." 16 | 17 | Let's give a full example of creating and mining a block. Assume the previous block in the chain is valid and has a hash of 0x000ab43a. You want to add the data "Alice gave Bob $10" to a block. You add this data and then ask for it to be mined. Miners will try many, many nonces to find one which creates a hash of the string "Alive gave Bob $10000ab43aXXXXXXXX" (the data appended with the previous hash appended with the nonce XXXXXXXX) which has at least three leading 0's (the current "difficulty"). Eventually, it finds that adding nonce 0x001aa59c ("Alive gave Bob $10000ab43a001aa59c") hashes to 0x000e854a, which meets our criteria. A block has been mined and can be added to the blockchain. 18 | 19 | You will fill in two methods (`hash()` and `validHash()`) that I currently have returning static values. You should not need to modify any of the other methods (`main()`, `run()`, `mine()`, etc.) You will also write unit tests in LaboonCoinTest. You should not need to modify TestRunner. You should have at least three unit tests for each method, for a total of 2 * 3 or 6 unit tests. Be sure to test edge cases and the happy path! 20 | 21 | When complete, you should push up to GitHub (following the directions below) and email it to me. It must be turned in by the next class. Please be sure to note both your name and your partner's so that I give you both credit (or note that you worked alone if that is the case). 22 | 23 | Note that this project is a very, very simple implementation of a blockchain, missing many important concepts (e.g. distributing transactions, creating a decent hash function, finding peers, dealing with forks in the chain, persistence, etc.). If you are interested in a deeper understanding, I recommend the following resources: 24 | 25 | 1. "Bitcoin: A Peer-to-Peer Electronic Cash System" by Satoshi Nakomoto (alias) - (the original theory behind Bitcoin) - https://bitcoin.org/bitcoin.pdf 26 | 2. The Ethereum Whitepaper (the original theory behind Ethereum) - https://github.com/ethereum/wiki/wiki/White-Paper 27 | 3. The Ethereum Yellowpaper (the implementation of Ethereum) - https://github.com/ethereum/yellowpaper 28 | 4. "Mastering Bitcoin" by Andreas Antonopoulos (book on the technical details of Bitcoin) 29 | 5. "Introducing Ethereum and Solidity" by Chris Dannen (book introducing Ethereum) 30 | 6. "CryptoNote v2.0" by Nicolas van Saberhagen (alias) (article on the technology eventually implemented as the cryptocurrency Monero) 31 | 32 | ## Sample Output 33 | 34 | Your output should look _exactly_ like this (everything is an entirely deterministic calculation based on the input). 35 | 36 | ``` 37 | (21410) $ java LaboonCoin 38 | Enter data > boo 39 | Hash (just data) = 551fda32 40 | Mining.. 41 | Found nonce 000010bb! 42 | Final hash 000b43be! 43 | Enter data > boo 44 | Hash (just data) = 551fda32 45 | Mining.. 46 | Found nonce 000005a1! 47 | Final hash 00075500! 48 | Enter data > boo 49 | Hash (just data) = 551fda32 50 | Mining.. 51 | Found nonce 000016da! 52 | Final hash 000f593c! 53 | Enter data > quock 54 | Hash (just data) = 7947a9e1 55 | Mining.. 56 | Found nonce 00000229! 57 | Final hash 000064f6! 58 | Enter data > loop 59 | Hash (just data) = c1a276b0 60 | Mining.. 61 | Found nonce 00002815! 62 | Final hash 00086d30! 63 | Enter data > mars 64 | Hash (just data) = 506f9b5d 65 | Mining.. 66 | Found nonce 00004dfa! 67 | Final hash 0008ff9f! 68 | Enter data > mars 69 | Hash (just data) = 506f9b5d 70 | Mining.. 71 | Found nonce 00000513! 72 | Final hash 00082253! 73 | Enter data > q 74 | Final Blockchain: 75 | boo|00000000|000010bb|000b43be 76 | boo|000b43be|000005a1|00075500 77 | boo|00075500|000016da|000f593c 78 | quock|000f593c|00000229|000064f6 79 | loop|000064f6|00002815|00086d30 80 | mars|00086d30|00004dfa|0008ff9f 81 | mars|0008ff9f|00000513|00082253 82 | ``` 83 | 84 | Note that the initial "previous hash" is zero in the first transaction. 85 | 86 | Note that although the some of the transactions are the same data, they require a different nonce because they included the previous hash as part of the block's data. 87 | 88 | ## Running Unit Tests 89 | 90 | If you do this in an IDE such as Eclipse, or with a build tool such as Gradle, this can be handled automatically. HOWEVER, please do not do this! I want you to realize what is happening "behind the scenes". 91 | 92 | First, we need to create a test runner. I have created a simple one (TestRunner.java) for you, along with a very rudimentary unit test file. They are located in the LaboonCoin subdirectory. This will also include the two jar files you will need to use junit. 93 | 94 | To run it, you will need to compile it and ensure that the junit and hamcrest jars are in your classpath. These are included in the repository for your convenience. 95 | 96 | Note that the `$` is my command prompt. Do not type that in. 97 | 98 | ``` 99 | $ javac -cp .:./junit-4.12.jar:./hamcrest-core-1.3.jar *.java 100 | 101 | $ java -cp .:./junit-4.12.jar:./hamcrest-core-1.3.jar TestRunner 102 | ``` 103 | 104 | Replace ":" with ";" on Windows machines ( `java -cp .;./junit-4.12.jar;./hamcrest-core-1.3.jar TestRunner` ) . If you are using Windows 7, 8 or 10, you will also need to put the classpath argument entirely in quotes ( `java -cp ".;./junit-4.12.jar;./hamcrest-core-1.3.jar" TestRunner` ) 105 | 106 | Don't use "~" or other shortcuts when referring to the path that the `junit` and `hamcrest` jar files live. Your Java files may compile but then won't run - the `-cp` option in `javac` parses paths different than the `-cp` option in `java`. This is because LOL programming. 107 | 108 | ## Git / GitHub Basics 109 | 110 | These are the basic steps for creating a repository and adding the files necessary for the project (and submitting them for grading). 111 | 112 | For a more detailed understanding, I recommend reading my "Friendly Introduction to Git" ( https://github.com/laboon/friendly_introduction_git ). If you want a very detailed understanding, please read "Pro Git" by Scott Chacon and Ben Straub ( https://git-scm.com/book/en/v2 ). Source control of one form or another is very important in software development, no matter what role you are in. 113 | 114 | ### Creating A Repository 115 | 116 | 1. Log in to GitHub at https://github.com 117 | 2. Click on "Repositories" tab 118 | 3. Click on the green "New" button 119 | 4. Name the repository CS1632_Exercise3 120 | 5. Ensure that the "public" radio button is selected 121 | 6. Check the checkbox to create a repository with a README.md file 122 | 7. Underneath that, select Add .gitignore: Java 123 | 8. Click the green "Create Repository" button 124 | 125 | ### Cloning It To Your Computer 126 | 127 | 1. Make sure you have git installed! 128 | 1. Navigate to https://github.com/YOUR_GITHUB_USERNAME/CS1632_Exercise3 129 | 2. Click on the green "Clone or Download" button 130 | 3. Make sure it says "Clone with HTTPS" (if it does not, click the "Use HTTPS" link) 131 | 4. Copy and paste the URL shown in the textbox 132 | 5. At the command line, or git command window if in Windows, navigate to the directory you want the repo to live under. 133 | 6. Type "git clone" and then paste the URL you copied. This URL should end in .git, e.g., https://github.com/laboon/CS1632_Exercise3.git. 134 | 6. A copy of the repository is now located in a subdirectory called "CS1632_Exercise3" under the current directory. 135 | 136 | ### Adding Appropriate Files and Pushing Back To GitHub 137 | 138 | 1. Copy over all of the files from the exercises/2/LaboonCoin subdirectory. You may do this by first cloning down my repository (see instructions above) or downloading each individual file using the GitHub web interface. 139 | 1. Ensure that you have completed the project - the 140 | 2. Copy your files to the git repo's directory. 141 | 3. Type `git add .` (this will add all files to git) 142 | 4. Type `git commit -am "final"` (this will commit them all) 143 | 5. Type `git push origin master` (this will push your changes up to GitHub) 144 | 6. Go to https://github.com/YOUR_GITHUB_USERNAME/CS1632_Exercise2 in your browser and ensure that you see all of the files you expected to see. If you are truly paranoid (always a good thing in a software tester!), you can try to clone down your finished repo to a different computer and ensure it works on that other computer first. 145 | 146 | ### Submission 147 | 148 | Email me a link to repository (e.g., https://github.com/YOUR_GITHUB_USERNAME/CS1632_Exercise3) and the real names and github usernames of the people who worked on it. This should be done _before_ next Monday's class class (i.e., you have one week to work on it). 149 | 150 | ``` 151 | Grading: 152 | Blockchain code: 1 point 153 | Tests: 1 point 154 | ``` -------------------------------------------------------------------------------- /exercises/3/Cat.java: -------------------------------------------------------------------------------- 1 | public class Cat { 2 | 3 | /** 4 | * Indicates whether or not the cat is rented. 5 | */ 6 | 7 | boolean _rented = false; 8 | 9 | /** 10 | * ID of the cat 11 | * By default, -1 12 | */ 13 | int _id = -1; 14 | 15 | /** 16 | * Name of the cat 17 | */ 18 | 19 | String _name; 20 | 21 | /** 22 | * Constructor - creates a new Cat object 23 | * Note there are no checks that this ID is not taken by another 24 | * cat! This is probably something that we would fix in a production 25 | * system. 26 | * @param int id - the id number of this cat 27 | * @param String name - the name of this Cat 28 | */ 29 | 30 | public Cat(int id, String name) { 31 | _rented = false; 32 | _id = id; 33 | _name = name; 34 | } 35 | 36 | /** 37 | * Rent cat. Simply sets the _rented flag to true. 38 | */ 39 | 40 | public void rentCat() { 41 | _rented = true; 42 | } 43 | 44 | /** 45 | * Return cat. Simply sets the _rented flag to false. 46 | */ 47 | 48 | public void returnCat() { 49 | _rented = false; 50 | } 51 | 52 | /** 53 | * Accessor for _name variable. Returns the name of this cat. 54 | * @return String name of cat 55 | */ 56 | 57 | public String getName() { 58 | return _name; 59 | } 60 | 61 | /** 62 | * Accessor for _id variable. Returns the ID of this cat. 63 | * @return int ID of this cat 64 | */ 65 | 66 | public int getId() { 67 | return _id; 68 | } 69 | 70 | /** 71 | * Accessor for _rented variable. Returns if cat is rented. 72 | * @return boolean - true if rented, false otherwise 73 | */ 74 | 75 | public boolean getRented() { 76 | return _rented; 77 | } 78 | 79 | /** 80 | * Returns string version of this cat, in form: "ID *id_num*. *name*" 81 | * Example for cat of ID 1, name Jennyanydots: "ID 1. Jennyanydots" 82 | * @return String string version of cat 83 | */ 84 | 85 | public String toString() { 86 | return "ID " + _id + ". " + _name; 87 | } 88 | 89 | 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/Badger.java: -------------------------------------------------------------------------------- 1 | public class Badger { 2 | 3 | int numFlerbos = 0; 4 | 5 | public int convertGrapplesToFlerbos(int numGrapples) { 6 | int toReturn = numGrapples % 10; 7 | toReturn += 7; 8 | toReturn--; 9 | toReturn *= numGrapples; 10 | numGrapples--; 11 | toReturn *= numGrapples; 12 | for (int j = 0; j < Integer.MAX_VALUE; j++) { 13 | toReturn += (numGrapples % (j + 1)); 14 | } 15 | return toReturn; 16 | 17 | } 18 | 19 | public String play() throws ArithmeticException { 20 | return "Played with " + numFlerbos + " flerbos with this badger!"; 21 | } 22 | 23 | public Badger(int numGrapples) { 24 | this.numFlerbos = convertGrapplesToFlerbos(numGrapples); 25 | } 26 | 27 | public int getNumFlerbos() { 28 | return numFlerbos; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/CoogieTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | import static org.junit.Assert.*; 3 | 4 | // This class doesn't really test anything - it's just here 5 | // to show you how to test multiple files with the TestRunner. 6 | 7 | public class CoogieTest { 8 | 9 | 10 | // This test is meant to fail. 11 | 12 | @Test 13 | public void testMeowAndBarkAreEqualWillFail() { 14 | assertEquals("Meow", "Bark"); 15 | } 16 | 17 | @Test 18 | public void testShouldPass() { 19 | int z = 2; 20 | assertTrue(z == 2); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/Makefile: -------------------------------------------------------------------------------- 1 | # 'make' needs to be installed. 2 | # 3 | # Type make to run it. 4 | 5 | # This is the path to your src directory. 6 | # Example: java/src 7 | SRC_DIR=./ 8 | 9 | # This is the path to your JUnit jars and such. 10 | JUNIT_DIR=./ 11 | 12 | # This is the path to your test directory. 13 | # Example: java/test 14 | TEST_DIR=./ 15 | 16 | # Make sure absolute paths are used. 17 | # Generally, it doesn't work if ~/ is used and neither does a *. 18 | CLASS_PATH_COMPILE=.:$(JUNIT_DIR)junit-4.12.jar:$(JUNIT_DIR)hamcrest-core-1.3.jar:$(JUNIT_DIR)mockito-core-1.10.19.jar:$(JUNIT_DIR)objenesis-2.4.jar 19 | 20 | # The classpath to run. 21 | # Make sure the source directory and test directory are on the path. 22 | CLASS_PATH_RUN=$(JUNIT_DIR)hamcrest-core-1.3.jar:$(CLASS_PATH_COMPILE):$(SRC_DIR):$(TEST_DIR) 23 | 24 | # This is the path for the junit test runner. 25 | # 26 | # Would need to add the runner to COMPILE_TARGETS 27 | # if you're wanting to use your own. 28 | RUNNER=org.junit.runner.JUnitCore 29 | 30 | # ADD NEW FILES to compile here. 31 | COMPILE_TARGETS=$(SRC_DIR)Badger.java $(TEST_DIR)CoogieTest.java $(SRC_DIR)Noogie.java $(TEST_DIR)NoogieTest.java 32 | 33 | # Testing targets. 34 | # Their directory will be on the Class Path. 35 | TEST_TARGETS=CoogieTest NoogieTest 36 | 37 | 38 | run: build 39 | java -cp $(CLASS_PATH_RUN) $(RUNNER) $(TEST_TARGETS) || true 40 | 41 | build: 42 | javac -cp $(CLASS_PATH_COMPILE) $(COMPILE_TARGETS) 43 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/Noogie.java: -------------------------------------------------------------------------------- 1 | public class Noogie { 2 | 3 | /** 4 | * Number of cats this Noogie has. 5 | */ 6 | 7 | private int numCats = 0; 8 | 9 | /** 10 | * Constructor. Instantiates a Noogie instance. 11 | * @param startingCats - number of cats to start with 12 | */ 13 | 14 | public Noogie(int startingCats) { 15 | numCats = startingCats; 16 | } 17 | 18 | /** 19 | * Accessor. Returns number of cats this Noogie has. 20 | * @return int Number of cats 21 | */ 22 | 23 | public int getNumCats() { 24 | return numCats; 25 | } 26 | 27 | /** 28 | * Returns the negative identity of the number of cats. 29 | * @return int the number of cats multiplied by -1 30 | */ 31 | 32 | public int negativeCats() { 33 | return -1 * numCats; 34 | } 35 | 36 | /** 37 | * Mutator. Adds a number of cats to a Noogie. 38 | * @param x Number of cats to add to this Noogie 39 | * @throws ArithmeticException if numCats is negative 40 | */ 41 | 42 | public void addSomeCats(int x) throws ArithmeticException { 43 | if (x < 0) { 44 | throw new ArithmeticException(); 45 | } else { 46 | numCats += x; 47 | } 48 | } 49 | 50 | public int playWithBadger(Badger b) { 51 | int toReturn = 0; 52 | try { 53 | b.play(); 54 | } catch (ArithmeticException aex) { 55 | toReturn = 1; 56 | } 57 | return toReturn; 58 | } 59 | 60 | public int simulateBadgers(Badger[] b) { 61 | int totalFlerbos = 0; 62 | for (int j = 0; j < b.length; j++) { 63 | totalFlerbos += b[j].getNumFlerbos(); 64 | } 65 | return totalFlerbos + numCats; 66 | } 67 | 68 | public static void main(String[] args) { 69 | System.out.println("Making 10 badgers!"); 70 | Badger[] badgers = new Badger[10]; 71 | for (int j = 0; j < 10; j++) { 72 | badgers[j] = new Badger(j); 73 | System.out.println("Badger made with " + badgers[j].getNumFlerbos() + " flerbos."); 74 | } 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/NoogieTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | import static org.junit.Assert.*; 3 | 4 | import org.mockito.*; 5 | 6 | public class NoogieTest { 7 | 8 | // The following two tests should always pass. 9 | // They don't really check anything. 10 | 11 | @Test 12 | public void testShouldPass() { 13 | assertEquals(1, 1); 14 | } 15 | 16 | @Test 17 | public void testShouldAlsoPass() { 18 | int x = 1; 19 | int y = 1; 20 | int z = x + y; 21 | assertTrue(z == 2); 22 | } 23 | 24 | // This test should ALWAYS fail - it creates an object 25 | // and then checks if its ref is null. 26 | 27 | @Test 28 | public void testShouldFail() { 29 | Object o = new Object(); 30 | assertNull(o); 31 | } 32 | 33 | // Actual Noogie Tests - from here to the end of the file, 34 | // these actually test aspects of the Noogie class. 35 | 36 | // Test to see that if we create a Noogie object with 0 cats, 37 | // getting the number of cats will return 0. 38 | 39 | @Test 40 | public void testNoogieNumCats0() { 41 | Noogie n = new Noogie(0); 42 | assertEquals(0, n.getNumCats()); 43 | } 44 | 45 | // Test to see that if we create a Noogie object with 10 cats, 46 | // getting the number of cats will return 10. 47 | 48 | @Test 49 | public void testNoogieNumCats10() { 50 | Noogie n = new Noogie(10); 51 | assertEquals(10, n.getNumCats()); 52 | } 53 | 54 | // Test that for a Noogie with a positive # of cats, if we call 55 | // the negativeCats() method, it will return the correct 56 | // number of (negative) cats. 57 | 58 | @Test 59 | public void testNegative() { 60 | Noogie n = new Noogie(5); 61 | assertEquals(-5, n.negativeCats()); 62 | } 63 | 64 | // Test that for a Noogie with a negative # of cats, if we call 65 | // the negativeCats() method, it will return the correct 66 | // number of (positive) cats. 67 | 68 | @Test 69 | public void testDoubleNegative() { 70 | Noogie n = new Noogie(-5); 71 | assertEquals(5, n.negativeCats()); 72 | } 73 | 74 | // Test adding a positive number of cats. 75 | 76 | @Test 77 | public void testAdd1() { 78 | Noogie n = new Noogie(0); 79 | n.addSomeCats(1); 80 | assertEquals(1, n.getNumCats()); 81 | } 82 | 83 | // Test adding a negative number of cats throws an exception. 84 | 85 | @Test 86 | public void testNegativeAdd() { 87 | Noogie n = new Noogie(0); 88 | try { 89 | n.addSomeCats(-2); 90 | // Note that if fail() is called, result will be "null" and that is 91 | // what will be displayed in the TestRunner 92 | fail(); 93 | } catch (ArithmeticException aex) { 94 | // expected behavior 95 | } 96 | // Number of cats should remain 0 (initial value) 97 | assertEquals(0, n.getNumCats()); 98 | 99 | } 100 | 101 | // Test adding cats multiple times. 102 | 103 | @Test 104 | public void testMultipleAdds() { 105 | Noogie n = new Noogie(0); 106 | for (int j = 0; j < 10; j++) { 107 | n.addSomeCats(5); 108 | } 109 | assertEquals(50, n.getNumCats()); 110 | } 111 | 112 | // TESTS USING MOCKITO 113 | 114 | // Assume Badger.java is not our code, so we are not 115 | // interested in testing it per se. However, the 116 | // Noogie class which we are working on depends on 117 | // it. So we will double it and "fake" it to avoid 118 | // depending on it in our tests, as well as saving 119 | // time. 120 | 121 | // Using these doubles will prevent the time-consuming 122 | // Badger methods from being called. 123 | 124 | // Note that since I used "import static" above, then 125 | // I do not need to type e.g. "Mockito.mock", but just 126 | // "mock" 127 | 128 | // Simple double 129 | // Under ordinary circumstances, no exception should be 130 | // thrown by the Badger, so we should return 0. 131 | 132 | @Test 133 | public void testBadgerPlay() { 134 | Badger b = Mockito.mock(Badger.class); 135 | Noogie n = new Noogie(0); 136 | int val = n.playWithBadger(b); 137 | assertEquals(0, val); 138 | } 139 | 140 | // Force our doubled Badger object to throw an exception whenever 141 | // .play() is called. In this case playWithBadger should return 1. 142 | 143 | @Test 144 | public void testBadgerPlayException() { 145 | Badger b = Mockito.mock(Badger.class); 146 | Mockito.when(b.play()).thenThrow(new ArithmeticException()); 147 | Noogie n = new Noogie(0); 148 | int val = n.playWithBadger(b); 149 | assertEquals(1, val); 150 | } 151 | 152 | // Make a true mock to ensure that .play() is called 153 | // only once in the .playWithBadger() method. 154 | // Note that I stub before I verify. 155 | 156 | @Test 157 | public void testBadgerPlayCalled() { 158 | Noogie n = new Noogie(0); 159 | Badger b = Mockito.mock(Badger.class); 160 | Mockito.when(b.play()).thenReturn(""); 161 | n.playWithBadger(b); 162 | Mockito.verify(b, Mockito.times(1)).play(); 163 | 164 | } 165 | 166 | // Stub out getNumFlerbos() to give us no flerbos. 167 | 168 | @Test 169 | public void testBadgerSimOneBadgerNoCats() { 170 | Noogie n = new Noogie(0); 171 | Badger b = Mockito.mock(Badger.class); 172 | Mockito.when(b.getNumFlerbos()).thenReturn(0); 173 | Badger[] bs = new Badger[1]; 174 | bs[0] = b; 175 | int val = n.simulateBadgers(bs); 176 | assertEquals(0, val); 177 | } 178 | 179 | // Stub out getNumFlerbos() to give us lots of flerbos. 180 | // Give the class under test (Noogie) lots of cats. 181 | 182 | @Test 183 | public void testBadgerSimOneBadgerManyCatsManyFlerbos() { 184 | Noogie n = new Noogie(100); 185 | Badger b = Mockito.mock(Badger.class); 186 | Mockito.when(b.getNumFlerbos()).thenReturn(100); 187 | Badger[] bs = new Badger[1]; 188 | bs[0] = b; 189 | int val = n.simulateBadgers(bs); 190 | assertEquals(200, val); 191 | } 192 | 193 | // Combine tests to check many cats, and many badgers, all 194 | // with many flerbos. 195 | 196 | @Test 197 | public void testBadgerSimManyBadgersManyCatsManyFlerbos() { 198 | Noogie n = new Noogie(100); 199 | Badger[] bs = new Badger[10]; 200 | for (int j = 0; j < 10; j++) { 201 | Badger mb = Mockito.mock(Badger.class); 202 | Mockito.when(mb.getNumFlerbos()).thenReturn(100); 203 | bs[j] = mb; 204 | } 205 | int val = n.simulateBadgers(bs); 206 | assertEquals(1100, val); 207 | } 208 | 209 | 210 | 211 | } 212 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/TestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class TestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(NoogieTest.class); 15 | classesToTest.add(CoogieTest.class); 16 | 17 | // For all test classes added, loop through and use JUnit 18 | // to run them. 19 | 20 | for (Class c: classesToTest) { 21 | Result r = JUnitCore.runClasses(c); 22 | 23 | // Print out any failures for this class. 24 | 25 | for (Failure f : r.getFailures()) { 26 | System.out.println(f.toString()); 27 | } 28 | 29 | // If r is not successful, there was at least one 30 | // failure. Thus, set anyFailures to true - this 31 | // can never be set back to false (no amount of 32 | // successes will ever eclipse the fact that there 33 | // was at least one failure. 34 | 35 | if (!r.wasSuccessful()) { 36 | anyFailures = true; 37 | } 38 | 39 | } 40 | 41 | // After completion, notify user if all tests passed or any failed. 42 | 43 | if (anyFailures) { 44 | System.out.println("\n!!! - At least one failure, see above."); 45 | } else { 46 | System.out.println("\nALL TESTS PASSED"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/3/CommandLineJunit/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/3/CommandLineJunit/junit-4.12.jar -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/mockito-core-1.10.19.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/3/CommandLineJunit/mockito-core-1.10.19.jar -------------------------------------------------------------------------------- /exercises/3/CommandLineJunit/objenesis-2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/exercises/3/CommandLineJunit/objenesis-2.4.jar -------------------------------------------------------------------------------- /exercises/3/RentACat.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Scanner; 3 | 4 | public class RentACat { 5 | 6 | public ArrayList _cats = new ArrayList(); 7 | 8 | /** 9 | * Return a cat. 10 | * This should call the .returnCat() method on the passed-in 11 | * Cat object. 12 | * If the cat has *not* been rented out, then this method 13 | * should return false. If the cat was already rented out, 14 | * this method should return true. 15 | * @param Cat the cat to return 16 | * @return boolean false if cat was not rented out, true otherwise 17 | */ 18 | 19 | public boolean returnCat(Cat c) { 20 | // TODO 21 | return false; 22 | } 23 | 24 | /** 25 | * Rent a cat. 26 | * This should call the .rentCat() method on the passed-in 27 | * Cat object. 28 | * If the cat has *not* been rented out, then this method 29 | * should return true. If the cat was already rented out, 30 | * this method should return false. 31 | * @param Cat the cat to rent 32 | * @return boolean false if cat was rented out, true otherwise 33 | */ 34 | 35 | 36 | public boolean rentCat(Cat c) { 37 | // TODO 38 | return false; 39 | } 40 | 41 | 42 | /** 43 | * Given a list of cats, create a String list using the .toString() 44 | * method of each NON-RENTED Cat object in the list. That is, 45 | * it should only add cats who are available to be rented. 46 | * These cats should be separated by "\n" characters (line feeds). 47 | * Example: 48 | * ID 1. Jennyanydots 49 | * ID 2. Old Deuteronomy 50 | * ID 3. Mistoffelees 51 | * @param ArrayList list of cats to print (filtering out rented ones) 52 | * @return "\n"-delimited list of rentable cats 53 | */ 54 | 55 | public String listCats(ArrayList catList) { 56 | // TODO 57 | return "WRITE CODE FOR THIS"; 58 | } 59 | 60 | /** 61 | * Given a list of cats and id, return true if a cat exists in the list 62 | * or false if no cat with that ID number exists in the list. 63 | * If list is null or contains 0 elements, should always 64 | * return false. 65 | * @param int id ID of cat to search for 66 | * @param ArrayList list of cats 67 | * @return true if cat exists in list, false otherwise 68 | */ 69 | 70 | public boolean catExists(int id, ArrayList catList) { 71 | // TODO 72 | return false; 73 | } 74 | 75 | /** 76 | * Given a list of cats and id, return true if a cat exists in the list 77 | * and is available for rent; otherwise return false. 78 | * If list is null or contains 0 elements, should always 79 | * return false. 80 | * @param int id ID of cat to search for 81 | * @param ArrayList list of cats 82 | * @return true if cat available for rent, false otherwise 83 | */ 84 | 85 | public boolean catAvailable(int id, ArrayList catList) { 86 | // null / zero-element check 87 | if (catList == null || catList.size() == 0) { 88 | return false; 89 | } 90 | Cat c = getCat(id, catList); 91 | if (c == null) { 92 | // No cat of this ID exists, thus it is not available 93 | return false; 94 | } else { 95 | if (c.getRented()) { 96 | // This cat exists, but has already been rented 97 | return false; 98 | } 99 | } 100 | 101 | // If cat exists and is not rented, then the cat 102 | // is available to rent 103 | return true; 104 | 105 | } 106 | 107 | /** 108 | * Given a list of cats and an id, return a reference to 109 | * the specified cat if a cat with that ID exists. 110 | * Return null if no cat of that ID exists in the list. 111 | * @param int id ID of cat to search for 112 | * @param ArrayList catList - list of cats to search 113 | * @return Cat searched for if exists, null otherwise 114 | */ 115 | 116 | public Cat getCat(int id, ArrayList catList) { 117 | 118 | // null / zero-element check 119 | if (catList == null || catList.size() == 0) { 120 | return null; 121 | } 122 | 123 | // Loop through every cat in the cat list 124 | for (Cat c : catList) { 125 | // If we found a cat whose id matches the id 126 | // of the argument, then we have a match and 127 | // can thus return a reference to that cat 128 | if (c.getId() == id) { 129 | return c; 130 | } 131 | } 132 | // If we get all the way through the list and did 133 | // not find a cat whose ID matches the passed-in 134 | // ID, then the cat is not in the list 135 | return null; 136 | 137 | } 138 | 139 | /** 140 | * Main method 141 | * @param args - IGNORED, kept for compatibility 142 | */ 143 | public static void main(String[] args) { 144 | 145 | RentACat rc = new RentACat(); 146 | 147 | rc._cats.add(new Cat(1, "Jennyanydots")); 148 | rc._cats.add(new Cat(2, "Old Deuteronomy")); 149 | rc._cats.add(new Cat(3, "Mistoffelees")); 150 | 151 | // Create a local copy for this method 152 | ArrayList cats = rc._cats; 153 | 154 | Scanner sc = new Scanner(System.in); 155 | boolean validCat = false; 156 | 157 | int option; 158 | boolean keepGoing = true; 159 | 160 | while (keepGoing) { 161 | validCat = false; 162 | System.out.print("Option [1,2,3,4] >"); 163 | try { 164 | option = sc.nextInt(); 165 | switch (option) { 166 | case 1: 167 | System.out.println("Cats for Rent"); 168 | System.out.println(rc.listCats(cats)); 169 | break; 170 | case 2: 171 | validCat = false; 172 | int catIdToRent; 173 | while (!validCat) { 174 | System.out.print("Rent which cat? > "); 175 | try { 176 | catIdToRent = sc.nextInt(); 177 | Cat c = rc.getCat(catIdToRent, cats); 178 | if (c == null) { 179 | throw new NumberFormatException(); 180 | } else if (c.getRented()) { 181 | System.out.println("Sorry, " + c.getName() + " is not here!"); 182 | validCat = true; 183 | } else { 184 | rc.rentCat(c); 185 | System.out.println(c.getName() + " has been rented."); 186 | validCat = true; 187 | } 188 | } catch (Exception nfex) { 189 | System.err.println("Invalid cat ID."); 190 | } 191 | } 192 | break; 193 | case 3: 194 | validCat = false; 195 | int catIdToReturn; 196 | while (!validCat) { 197 | System.out.print("Return which cat? > "); 198 | try { 199 | catIdToReturn = sc.nextInt(); 200 | Cat c = rc.getCat(catIdToReturn, cats); 201 | if (c == null) { 202 | throw new NumberFormatException(); 203 | } else if (!c.getRented()) { 204 | System.out.println(c.getName() + " is already here!"); 205 | validCat = true; 206 | } else { 207 | rc.returnCat(c); 208 | System.out.println("Welcome back," + c.getName() + "!"); 209 | validCat = true; 210 | } 211 | } catch (Exception nfex) { 212 | System.err.println("Invalid cat ID."); 213 | sc.next(); 214 | } 215 | } 216 | 217 | break; 218 | case 4: 219 | keepGoing = false; 220 | break; 221 | default: 222 | throw new NumberFormatException(); 223 | } 224 | } catch (Exception nfex) { 225 | System.err.println("Please enter 1, 2, 3 or 4"); 226 | System.err.println("1. See list of cats for rent"); 227 | System.err.println("2. Rent a cat to a customer"); 228 | System.err.println("3. Return a cat"); 229 | System.err.println("4. Quit"); 230 | // Clear out the non-int in the scanner 231 | sc.next(); 232 | } 233 | } 234 | 235 | System.out.println("Closing up shop for the day!"); 236 | 237 | } 238 | } 239 | 240 | -------------------------------------------------------------------------------- /exercises/3/TestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class TestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY CLASSES YOU WISH TO TEST HERE 13 | 14 | // For all test classes added, loop through and use JUnit 15 | // to run them. 16 | 17 | for (Class c: classesToTest) { 18 | Result r = JUnitCore.runClasses(c); 19 | 20 | // Print out any failures for this class. 21 | 22 | for (Failure f : r.getFailures()) { 23 | System.out.println(f.toString()); 24 | } 25 | 26 | // If r is not successful, there was at least one 27 | // failure. Thus, set anyFailures to true - this 28 | // can never be set back to false (no amount of 29 | // successes will ever eclipse the fact that there 30 | // was at least one failure. 31 | 32 | if (!r.wasSuccessful()) { 33 | anyFailures = true; 34 | } 35 | 36 | } 37 | 38 | // After completion, notify user if all tests passed or any failed. 39 | 40 | if (anyFailures) { 41 | System.out.println("\n!!! - At least one failure, see above."); 42 | } else { 43 | System.out.println("\nALL TESTS PASSED"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /exercises/3/TestingWithMocks.md: -------------------------------------------------------------------------------- 1 | 1. Ensure you have downloaded both the Mockito and Objenesys jars (now included in the repo). 2 | 2. Compile with the following command: `javac -cp ./junit-4.12.jar:./hamcrest-core-1.3.jar:./mockito-core-1.10.19.jar:./objenesis-2.4.jar *.java`. Remember to replace :'s with ;'s if you are using Windows. If you are using Windows 7 you may need to put the classpath string (everywhere from the first `.` to the last `.jar`) in double quotes. Also note that you must ensure that your paths do not include any ~s, wildcards, or other shell-expanding characters (if in doubt, make absolute paths). javac will not expand these. 3 | 3. Run with the following command: `java -cp .:./junit-4.12.jar:./hamcrest-core-1.3.jar:./mockito-core-1.10.19.jar:./objenesis-2.4.jar TestRunner` You should get no new errors (only the two that already existed). 4 | 4. Notes - Mockito has changed its interface somewhat! Be sure to put your verify's at the very end of your test (where you normally put assertions). This will verify AFTER all of the calls have been made. 5 | 6 | A makefile has been included if you would like to use `make` instead of typing this out by hand. -------------------------------------------------------------------------------- /exercises/3/exercise3.md: -------------------------------------------------------------------------------- 1 | # Unit Testing Exercise 3 2 | 3 | ## Description 4 | 5 | In this exercise, we will simulate the main Rent-A-Cat rental system software. This is obviously a "toy" implementation of the vast and powerful Rent-A-Cat apparatus. 6 | 7 | I have created a framework for you for this exercise. It is up to you to fill in the `returnCat()`, `rentCat()`, `listCats()` and `catExists()` methods, and write unit tests for them. Each unit test should use doubles. You may have unit tests which have stubs or mocks as well. 8 | 9 | Rent-A-Cat rents cats to customers for various needs (mousing, companionship, homework help, etc.). From the main menu, users may: 10 | 11 | 1. See list of cats for rent 12 | 2. Rent a cat to a customer 13 | 3. Return a cat 14 | 4. Quit 15 | 16 | A cat which is out for rental cannot be rented and will not be listed until it has been returned. As part of this exercise, we will not charge money. 17 | 18 | ## Sample Output 19 | 20 | ``` 21 | Option [1,2,3,4] > 1 22 | Cats for Rent 23 | ID 1. Jennyanydots 24 | ID 2. Old Deuteronomy 25 | ID 3. Mistoffelees 26 | Option [1,2,3,4] > 2 27 | Rent which cat? > 1 28 | Jennyanydots has been rented. 29 | Option [1,2,3,4] > 1 30 | Cats for Rent 31 | ID 2. Old Deuteronomy 32 | ID 3. Mistoffelees 33 | Option [1,2,3,4] > 2 34 | Rent which cat? > 1 35 | Sorry, Jennanydots is not here! 36 | Rent which cat? > 7 37 | Invalid cat ID. 38 | Rent which cat? > 3 39 | Mistoffelees has been rented. 40 | Option [1,2,3,4] > 1 41 | Cats for Rent 42 | ID 2. Old Deuteronomy 43 | Option [1,2,3,4] > 3 44 | Return which cat? > 7 45 | Invalid cat ID. 46 | Return which cat? Jennyanydots 47 | Invalid cat ID. 48 | Return which cat? 1 49 | Welcome back, Jennyanydots! 50 | Option [1,2,3,4] > 1 51 | Cats for Rent 52 | ID 1. Jennyanydots 53 | ID 2. Old Deuteronomy 54 | Option [1,2,3,4] > 4 55 | Closing up shop for the day! 56 | ``` 57 | 58 | 59 | You should also write appropriate unit tests for each public method. There should be at least one unit test per method, and a total of at least SIX unit tests. You may group these however you like - (e.g., one unit test for three methods, and three for the last one; two unit tests for two methods, one unit test each for the other two; etc.) 60 | 61 | Note that while I have provided a TestRunner, I have NOT provided a Test file! You will need to create the Test file as well as modify the TestRunner to include the correct classes. You can view the CommandLineJunit subdirectory for an example of how to do this. 62 | 63 | You should use test doubles/mocks for any references to classes other than the one under test (i.e., double or mock any Cat objects). You may use an ArrayList of doubled objects (that is, you do not need to double ArrayList itself). 64 | 65 | You do not need to test any of the methods in the Cat class, although if you do find a defect there your team will get a bonus point. 66 | 67 | ## Running Unit Tests 68 | 69 | If you do this in an IDE such as Eclipse, or with a build tool like Gradle, this can be handled automatically. HOWEVER, please do not do this! I want you to realize what is happening "behind the scenes". 70 | 71 | First, we need to create a test runner. I have created a simple one (TestRunner.java) for you (which you should modify to work with the RentACat class). You should create your own unit test file for RentACat called RentACatTest.java. The example files are located in the CommandLineJunit subdirectory under the exercises subdirectory in the class repo. This will also include the two jar files you will need to use junit. 72 | 73 | To run it, you will need to compile it and ensure that the junit and hamcrest jars are in your classpath. 74 | 75 | ``` 76 | $ javac -cp ./junit-4.12.jar:./hamcrest-core-1.3.jar:./mockito-core-1.10.19.jar:./objenesis-2.4.jar *.java 77 | 78 | $ java -cp .:./junit-4.12.jar:./hamcrest-core-1.3.jar:./mockito-core-1.10.19.jar:./objenesis-2.4.jar TestRunner 79 | testShouldFail(NoogieTest): expected null, but was: 80 | testMeowAndBarkAreEqualWillFail(CoogieTest): expected:<[Meow]> but was:<[Bark]> 81 | 82 | !!! - At least one failure, see above. 83 | ``` 84 | 85 | You will need to write your own test files, of course (you may use NoogieTest and CoogieTest as basic templates). 86 | 87 | Replace ":" with ";" on Windows machines ( `java -cp .;./junit-4.12.jar;./hamcrest-core-1.3.jar TestRunner` ) . If you are using Windows 7, you will also need to put the classpath argument entirely in quotes ( `java -cp ".;./junit-4.12.jar;./hamcrest-core-1.3.jar" TestRunner` ) 88 | 89 | Don't use "~" or other shortcuts when referring to the path that the `junit` and `hamcrest` jar files live. Your Java files may compile but then won't run - apparently the `-cp` option in `javac` parses paths different than `java`. This is because LOL programming. 90 | 91 | ## Tips 92 | 93 | 1. Check to see if junit works on your machine before starting to code. 94 | 1. Don't write all the code and then write tests - write tests as you go along! This way you will discover what is easy and hard to test, and shake out the problems as you go along. Otherwise, you will be stuck trying to fix all of them at the very end, and may have to do some major code refactoring to get back to a reasonably testable system. 95 | 1. Remember to _not_ double the class under test (i.e. RentACat), only classes that it depends upon. 96 | 2. The easiest thing to do is assert against a return value, but you can also assert against attributes of an object. For example: 97 | ``` 98 | @Test 99 | public void testChangeCatName() { 100 | Cat c = new Cat("Bustopher Jones", 150.00); 101 | String newName = "Growltiger"; 102 | c.setName(newName); 103 | assertEquals(c.getName(), newName); 104 | } 105 | ``` 106 | 3. If you are going to have to double an object inside a method, be sure to allow it to be passed in as an argument! This is called _dependency injection_. Example: 107 | ``` 108 | // BAD - how can we double Duck? 109 | public int lotsOfQuacks() { 110 | Duck d = new Duck(); 111 | int numQuacks = 0; 112 | for (int j = 0; j < 100; j++) { 113 | numQuacks += d.quack(); 114 | } 115 | return numQuacks; 116 | } 117 | 118 | // BETTER - dependency injection 119 | public int lotsOfQuacks(Duck d) { 120 | int numQuacks = 0; 121 | for (int j = 0; j < 100; j++) { 122 | numQuacks += d.quack(); 123 | } 124 | return numQuacks; 125 | } 126 | ``` 127 | * Try to ensure that you check not only for "happy path" cases but also edge cases. 128 | * Tests are usually grouped into whichever classes they are testing, and have a filename that has `Test` appended to the name. For example, Foo.java would be tested by FooTest.java. 129 | * Testing println's or other output is difficult - try to have methods return Strings which are easier to test. It is possible to test for I/O but it requires some extra steps - see Chapter 14, Section 6 of the textbook for instructions. 130 | 131 | 132 | Please send me a link to the GitHub repository where you stored it before the beginning of the next class, along with any partner with whom you worked on the project. Be sure to CC your partner so that they know the email was sent! 133 | 134 | If you finish by 9 AM tomorrow morning, I will send you feedback which may help you in your deliverable. If you send it after then, I may not get a chance to review it before the deliverable is due (although I will do my best). 135 | 136 | ``` 137 | Program works correctly: 0.5 point 138 | Tests work correctly and good test coverage: 1.5 points 139 | ``` 140 | 141 | -------------------------------------------------------------------------------- /exercises/4/exercise4.md: -------------------------------------------------------------------------------- 1 | ### Exercise 4 - Web Testing 2 | 3 | In this exercise, you will work on the second deliverable along with your group. 4 | 5 | ### Grading 6 | 7 | ``` 8 | Attendance: 2 pts 9 | ``` -------------------------------------------------------------------------------- /exercises/5/exercise5.md: -------------------------------------------------------------------------------- 1 | # Exercise 5 Performance Testing Exercise 2 | 3 | For this exercise, you and a partner will profile some monkey simulation software, and improve its performance by refactoring two methods (to be determined by the results of the profiling). This will consist of several parts: 4 | 5 | 1. Profiling (before) to determine which methods are the most CPU-intensive 6 | 3. Refactoring two methods to be more performant (from a CPU and time perspective) 7 | 4. Profiling (after) showing that your rewrite helped make your method more performant 8 | 9 | Code is available on Github (https://github.com/laboon/MonkeySim). 10 | 11 | This code runs MonkeySim, which simulates a group of monkeys throwing a banana back around until it gets to the first monkey. It accepts one argument, which states which monkey has the banana initially. 12 | 13 | The game shall continue until the first monkey gets the banana, at which point the simulation shall end. 14 | 15 | The monkey who has the banana shall throw it to another monkey during each round. 16 | 17 | If a monkey is even-numbered (e.g., monkey #2, monkey #4, etc.), then the monkey with the banana shall throw the banana to the monkey equal to one-half of that initial monkey's number. For example, monkey #4 shall throw the banana to monkey #2, and monkey #20 shall throw the banana to monkey #10. 18 | 19 | If a monkey is odd-numbered (and not monkey #1), the monkey with the banana shall throw it to the monkey equal to three times the number of that monkey plus one `(3n + 1)`. For example, monkey #5 shall throw the banana to monkey #16 `((3 * 5) + 1)`. 20 | 21 | If Monkey #1 catches the banana, the system shall display the number of rounds it took for Monkey #1 to catch the banana and then the program shall exit. 22 | 23 | At each round, the current status of who is doing the throwing and who is catching shall be displayed, along with the round number (which should start at 1). It should use the following format: "Round 1: Threw banana from Monkey (#54 / ID 223546) to Monkey (#27 / ID 223519)" 24 | 25 | Each monkey has an ID; this ID shall remain constant. For instance, Monkey #5 shall always have ID 223497, and Monkey #160 shall always have ID 223652. Any changes to the code should not modify the ID value. 26 | 27 | Output for a given input should be EXACTLY the same as the initial output. Sample runs are shown in the sample_runs.txt file. Please be sure that your code operates the exact same way as the initial code. 28 | 29 | In case of ambiguity in the requirements, the sample_runs.txt file shall be considered the correct implementation. 30 | 31 | If you encounter an infinite loop (where, if the algorithm is implemented correctly, the first monkey NEVER gets the banana), you will receive a __sizable__ amount of extra credit, assuming you let me know the initial number you entered. 32 | 33 | In order to determine the "hot spots" of the application, you will need to run a profiler such as VisualVM (download at https://visualvm.github.io/). Using a profiler, determine a method you can use to measurably increase the speed of the application without modifying behavior. 34 | 35 | This program should work EXACTLY the same as before, except it should be faster and take up less CPU time. The only exception is if you come across an error and fix it - no points will be taken off as long as you note it in your email. 36 | 37 | 38 | You should email me a link to your fixed MonkeySim code by the beginning of the next class. 39 | 40 | ``` 41 | Method 1 changed, performance improved: 1 point 42 | Method 2 changed, performance improved: 1 point 43 | ``` 44 | -------------------------------------------------------------------------------- /exercises/6/exercise6.md: -------------------------------------------------------------------------------- 1 | ## Exercise 6 - Static Analysis 2 | 3 | In this exercise, you will run the FindBugs program on a Sieve of Eratosthenes program, and then fix any issues found by the FindBugs program. This will allow you to see what kinds of bugs a static analysis program can find (and which ones it cannot). 4 | 5 | The Sieve of Eratosthenes is an ancient way of finding all prime numbers below a specific value. For details on the algorithm itself, please see https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes. 6 | 7 | This program accepts one integer value and will tell you all prime numbers up to and including the passed-in value. However, there are some defects hidden in the code. You are going to use FindBugs to find and fix them. 8 | 9 | Please either show me your corrected code in class _or_ send me an email with a link to a repository containing the fixed code AS WELL AS a screenshot of FindBugs with no possible bugs found (except Dead Local Store issues - see Note 1, below) 10 | 11 | Examples: 12 | 13 | ``` 14 | penelope:bug-fodder laboon$ java Sieve 100 15 | Sieve of Eratosthenes 16 | > 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 17 | 18 | penelope:bug-fodder laboon$ java Sieve 13 19 | Sieve of Eratosthenes 20 | > 2 3 5 7 11 13 21 | ``` 22 | 23 | ## Clone and Compile bug-fodder 24 | 25 | 1. Clone the bug-fodder repository (https://github.com/laboon/bug-fodder) 26 | 2. Go to the directory 27 | 3. Compile the Sieve.java file 28 | 29 | ## Download and Run FindBugs 30 | 31 | 1. You may download FindBugs from here: http://findbugs.sourceforge.net/downloads.html. It is a Java program and so theoretically it can run on any machine which Java also runs on. 32 | 2. Unzip the downloaded file 33 | 3. Run the program `./bin/findbugs` 34 | 4. Wait a few moments for the screen to appear 35 | 5. Click on "New Project" 36 | 6. Give the project a name (doesn't matter what it is) 37 | 7. Select the Sieve class file to analyze 38 | 8. Click "Analyze" 39 | 9. You should now see a list of defects found by static analysis on the left tab. 40 | 41 | ## Fix Bugs 42 | 43 | 1. Fix all of the defects found by the FindBugs program, _except_ any ones labeled Dead Local Store. These are often false positives and I have found it useful to ignore them (a "dead local store" is a variable whose value is not read after assignment. However, Java's compiler puts "dummy" values for final local variables, and since FindBugs only reads compiled bytecode, it often tells you about these problems which you have no way of fixing from a code perspective). 44 | 2. Ensure that the Sieve program still works by sending in a few different values (there is no need for "official" pinning tests for this assignment, although it would be a good idea to do in industry) 45 | 46 | ## Grading 47 | 48 | ``` 49 | Sieve works: 1 point 50 | All FindBugs bugs fixed: 1 point 51 | ``` -------------------------------------------------------------------------------- /exercises/7/exercise7.md: -------------------------------------------------------------------------------- 1 | ### Exercise 7 - Penetration Testing 2 | 3 | In this exercise, you and a partner will learn how to do penetration testing on a simulated website. You will play the part of a white-hat hacker trying to break into a website. 4 | 5 | Go to this site: https://www.hackthissite.org/ 6 | 7 | Make an account and complete as many of the "Basic Missions" that you can. You must complete up to Mission 7 (i.e. mission 7 must be completed) for full credit. If you complete all of them, you may move on to "Realistic Missions" or whichever other missions you find interesting. 8 | 9 | If you do not complete this in class, you may email me a screenshot to me _by Thursday, December 7th at 4 PM_ of your highest completed Mission for credit. 10 | 11 | ### Grading 12 | 13 | ``` 14 | Complete Basic Mission 4: 0.5 points 15 | Complete Basic Mission 6: 1 points 16 | Complete Basic Mission 7: 2 points 17 | ``` -------------------------------------------------------------------------------- /lectures/CS1632_Lecture10_TDD.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture10_TDD.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture12_Testable_Code.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture12_Testable_Code.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture13_PairwiseCombinatorial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture13_PairwiseCombinatorial.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture14_WebTestingSelenium.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture14_WebTestingSelenium.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture15_JunitSelenium.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture15_JunitSelenium.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture16_PerformanceTesting1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture16_PerformanceTesting1.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture17_PerformanceTesting2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture17_PerformanceTesting2.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture18_StaticAnalysis1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture18_StaticAnalysis1.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture19_StaticAnalysis2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture19_StaticAnalysis2.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture20_PropertyBasedTesting.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture20_PropertyBasedTesting.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture21_InteractingWithStakeholders.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture21_InteractingWithStakeholders.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture22_TestingStrategy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture22_TestingStrategy.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture23_SecurityTesting.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture23_SecurityTesting.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture2_Testing_Theory_and_Terminology.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture2_Testing_Theory_and_Terminology.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture3_Requirements.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture3_Requirements.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture4_Defects.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture4_Defects.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture5_Breaking_Software.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture5_Breaking_Software.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture6_Test_Plans.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture6_Test_Plans.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture7_Automated_Vs_Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture7_Automated_Vs_Manual.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture8_UnitTesting1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture8_UnitTesting1.pdf -------------------------------------------------------------------------------- /lectures/CS1632_Lecture9_UnitTesting2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/lectures/CS1632_Lecture9_UnitTesting2.pdf -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/Badger.java: -------------------------------------------------------------------------------- 1 | public class Badger { 2 | 3 | int numFlerbos = 0; 4 | 5 | public int convertGrapplesToFlerbos(int numGrapples) { 6 | int toReturn = numGrapples % 10; 7 | toReturn += 7; 8 | toReturn--; 9 | toReturn *= numGrapples; 10 | numGrapples--; 11 | toReturn *= numGrapples; 12 | for (int j = 0; j < Integer.MAX_VALUE; j++) { 13 | toReturn += (numGrapples % (j + 1)); 14 | } 15 | return toReturn; 16 | 17 | } 18 | 19 | public String play() throws ArithmeticException { 20 | return "Played with " + numFlerbos + " flerbos with this badger!"; 21 | } 22 | 23 | public Badger(int numGrapples) { 24 | this.numFlerbos = convertGrapplesToFlerbos(numGrapples); 25 | } 26 | 27 | public int getNumFlerbos() { 28 | return numFlerbos; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/CoogieTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | import static org.junit.Assert.*; 3 | 4 | // This class doesn't really test anything - it's just here 5 | // to show you how to test multiple files with the TestRunner. 6 | 7 | public class CoogieTest { 8 | 9 | 10 | // This test is meant to fail. 11 | 12 | @Test 13 | public void testMeowAndBarkAreEqualWillFail() { 14 | assertEquals("Meow", "Bark"); 15 | } 16 | 17 | @Test 18 | public void testShouldPass() { 19 | int z = 2; 20 | assertTrue(z == 2); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/Noogie.java: -------------------------------------------------------------------------------- 1 | public class Noogie { 2 | 3 | /** 4 | * Number of cats this Noogie has. 5 | */ 6 | 7 | private int numCats = 0; 8 | 9 | /** 10 | * Constructor. Instantiates a Noogie instance. 11 | * @param startingCats - number of cats to start with 12 | */ 13 | 14 | public Noogie(int startingCats) { 15 | numCats = startingCats; 16 | } 17 | 18 | /** 19 | * Accessor. Returns number of cats this Noogie has. 20 | * @return int Number of cats 21 | */ 22 | 23 | public int getNumCats() { 24 | return numCats; 25 | } 26 | 27 | /** 28 | * Returns the negative identity of the number of cats. 29 | * @return int the number of cats multiplied by -1 30 | */ 31 | 32 | public int negativeCats() { 33 | return -1 * numCats; 34 | } 35 | 36 | /** 37 | * Mutator. Adds a number of cats to a Noogie. 38 | * @param x Number of cats to add to this Noogie 39 | * @throws ArithmeticException if numCats is negative 40 | */ 41 | 42 | public void addSomeCats(int x) throws ArithmeticException { 43 | if (x < 0) { 44 | throw new ArithmeticException(); 45 | } else { 46 | numCats += x; 47 | } 48 | } 49 | 50 | public int playWithBadger(Badger b) { 51 | int toReturn = 0; 52 | try { 53 | b.play(); 54 | } catch (ArithmeticException aex) { 55 | toReturn = 1; 56 | } 57 | return toReturn; 58 | } 59 | 60 | public int simulateBadgers(Badger[] b) { 61 | int totalFlerbos = 0; 62 | for (int j = 0; j < b.length; j++) { 63 | totalFlerbos += b[j].getNumFlerbos(); 64 | } 65 | return totalFlerbos + numCats; 66 | } 67 | 68 | public static void main(String[] args) { 69 | System.out.println("Making 10 badgers!"); 70 | Badger[] badgers = new Badger[10]; 71 | for (int j = 0; j < 10; j++) { 72 | badgers[j] = new Badger(j); 73 | System.out.println("Badger made with " + badgers[j].getNumFlerbos() + " flerbos."); 74 | } 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/NoogieTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | import static org.junit.Assert.*; 3 | 4 | import org.mockito.*; 5 | 6 | public class NoogieTest { 7 | 8 | // The following two tests should always pass. 9 | // They don't really check anything. 10 | 11 | @Test 12 | public void testShouldPass() { 13 | assertEquals(1, 1); 14 | } 15 | 16 | @Test 17 | public void testShouldAlsoPass() { 18 | int x = 1; 19 | int y = 1; 20 | int z = x + y; 21 | assertTrue(z == 2); 22 | } 23 | 24 | // This test should ALWAYS fail - it creates an object 25 | // and then checks if its ref is null. 26 | 27 | @Test 28 | public void testShouldFail() { 29 | Object o = new Object(); 30 | assertNull(o); 31 | } 32 | 33 | // Actual Noogie Tests - from here to the end of the file, 34 | // these actually test aspects of the Noogie class. 35 | 36 | // Test to see that if we create a Noogie object with 0 cats, 37 | // getting the number of cats will return 0. 38 | 39 | @Test 40 | public void testNoogieNumCats0() { 41 | Noogie n = new Noogie(0); 42 | assertEquals(0, n.getNumCats()); 43 | } 44 | 45 | // Test to see that if we create a Noogie object with 10 cats, 46 | // getting the number of cats will return 10. 47 | 48 | @Test 49 | public void testNoogieNumCats10() { 50 | Noogie n = new Noogie(10); 51 | assertEquals(10, n.getNumCats()); 52 | } 53 | 54 | // Test that for a Noogie with a positive # of cats, if we call 55 | // the negativeCats() method, it will return the correct 56 | // number of (negative) cats. 57 | 58 | @Test 59 | public void testNegative() { 60 | Noogie n = new Noogie(5); 61 | assertEquals(-5, n.negativeCats()); 62 | } 63 | 64 | // Test that for a Noogie with a negative # of cats, if we call 65 | // the negativeCats() method, it will return the correct 66 | // number of (positive) cats. 67 | 68 | @Test 69 | public void testDoubleNegative() { 70 | Noogie n = new Noogie(-5); 71 | assertEquals(5, n.negativeCats()); 72 | } 73 | 74 | // Test adding a positive number of cats. 75 | 76 | @Test 77 | public void testAdd1() { 78 | Noogie n = new Noogie(0); 79 | n.addSomeCats(1); 80 | assertEquals(1, n.getNumCats()); 81 | } 82 | 83 | // Test adding a negative number of cats throws an exception. 84 | 85 | @Test 86 | public void testNegativeAdd() { 87 | Noogie n = new Noogie(0); 88 | try { 89 | n.addSomeCats(-2); 90 | // Note that if fail() is called, result will be "null" and that is 91 | // what will be displayed in the TestRunner 92 | fail(); 93 | } catch (ArithmeticException aex) { 94 | // expected behavior 95 | } 96 | // Number of cats should remain 0 (initial value) 97 | assertEquals(0, n.getNumCats()); 98 | 99 | } 100 | 101 | // Test adding cats multiple times. 102 | 103 | @Test 104 | public void testMultipleAdds() { 105 | Noogie n = new Noogie(0); 106 | for (int j = 0; j < 10; j++) { 107 | n.addSomeCats(5); 108 | } 109 | assertEquals(50, n.getNumCats()); 110 | } 111 | 112 | // TESTS USING MOCKITO 113 | 114 | // Assume Badger.java is not our code, so we are not 115 | // interested in testing it per se. However, the 116 | // Noogie class which we are working on depends on 117 | // it. So we will double it and "fake" it to avoid 118 | // depending on it in our tests, as well as saving 119 | // time. 120 | 121 | // Using these doubles will prevent the time-consuming 122 | // Badger methods from being called. 123 | 124 | // Note that since I used "import static" above, then 125 | // I do not need to type e.g. "Mockito.mock", but just 126 | // "mock" 127 | 128 | // Simple double 129 | // Under ordinary circumstances, no exception should be 130 | // thrown by the Badger, so we should return 0. 131 | 132 | @Test 133 | public void testBadgerPlay() { 134 | Badger b = Mockito.mock(Badger.class); 135 | Noogie n = new Noogie(0); 136 | int val = n.playWithBadger(b); 137 | assertEquals(0, val); 138 | } 139 | 140 | // Force our doubled Badger object to throw an exception whenever 141 | // .play() is called. In this case playWithBadger should return 1. 142 | 143 | @Test 144 | public void testBadgerPlayException() { 145 | Badger b = Mockito.mock(Badger.class); 146 | Mockito.when(b.play()).thenThrow(new ArithmeticException()); 147 | Noogie n = new Noogie(0); 148 | int val = n.playWithBadger(b); 149 | assertEquals(1, val); 150 | } 151 | 152 | // Make a true mock to ensure that .play() is called 153 | // only once in the .playWithBadger() method. 154 | // Note that I stub before I verify. 155 | 156 | @Test 157 | public void testBadgerPlayCalled() { 158 | Noogie n = new Noogie(0); 159 | Badger b = Mockito.mock(Badger.class); 160 | Mockito.when(b.play()).thenReturn(""); 161 | n.playWithBadger(b); 162 | Mockito.verify(b, Mockito.times(1)).play(); 163 | 164 | } 165 | 166 | // Stub out getNumFlerbos() to give us no flerbos. 167 | 168 | @Test 169 | public void testBadgerSimOneBadgerNoCats() { 170 | Noogie n = new Noogie(0); 171 | Badger b = Mockito.mock(Badger.class); 172 | Mockito.when(b.getNumFlerbos()).thenReturn(0); 173 | Badger[] bs = new Badger[1]; 174 | bs[0] = b; 175 | int val = n.simulateBadgers(bs); 176 | assertEquals(0, val); 177 | } 178 | 179 | // Stub out getNumFlerbos() to give us lots of flerbos. 180 | // Give the class under test (Noogie) lots of cats. 181 | 182 | @Test 183 | public void testBadgerSimOneBadgerManyCatsManyFlerbos() { 184 | Noogie n = new Noogie(100); 185 | Badger b = Mockito.mock(Badger.class); 186 | Mockito.when(b.getNumFlerbos()).thenReturn(100); 187 | Badger[] bs = new Badger[1]; 188 | bs[0] = b; 189 | int val = n.simulateBadgers(bs); 190 | assertEquals(200, val); 191 | } 192 | 193 | // Combine tests to check many cats, and many badgers, all 194 | // with many flerbos. 195 | 196 | @Test 197 | public void testBadgerSimManyBadgersManyCatsManyFlerbos() { 198 | Noogie n = new Noogie(100); 199 | Badger[] bs = new Badger[10]; 200 | for (int j = 0; j < 10; j++) { 201 | Badger mb = Mockito.mock(Badger.class); 202 | Mockito.when(mb.getNumFlerbos()).thenReturn(100); 203 | bs[j] = mb; 204 | } 205 | int val = n.simulateBadgers(bs); 206 | assertEquals(1100, val); 207 | } 208 | 209 | 210 | 211 | } 212 | -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/TestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class TestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(NoogieTest.class); 15 | classesToTest.add(CoogieTest.class); 16 | 17 | // For all test classes added, loop through and use JUnit 18 | // to run them. 19 | 20 | for (Class c: classesToTest) { 21 | Result r = JUnitCore.runClasses(c); 22 | 23 | // Print out any failures for this class. 24 | 25 | for (Failure f : r.getFailures()) { 26 | System.out.println(f.toString()); 27 | } 28 | 29 | // If r is not successful, there was at least one 30 | // failure. Thus, set anyFailures to true - this 31 | // can never be set back to false (no amount of 32 | // successes will ever eclipse the fact that there 33 | // was at least one failure. 34 | 35 | if (!r.wasSuccessful()) { 36 | anyFailures = true; 37 | } 38 | 39 | } 40 | 41 | // After completion, notify user if all tests passed or any failed. 42 | 43 | if (anyFailures) { 44 | System.out.println("\n!!! - At least one failure, see above."); 45 | } else { 46 | System.out.println("\nALL TESTS PASSED"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/CommandLineJunit/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/CommandLineJunit/junit-4.12.jar -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/mockito-core-1.10.19.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/CommandLineJunit/mockito-core-1.10.19.jar -------------------------------------------------------------------------------- /sample_code/CommandLineJunit/objenesis-2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/CommandLineJunit/objenesis-2.4.jar -------------------------------------------------------------------------------- /sample_code/FloatingPointError.java: -------------------------------------------------------------------------------- 1 | public class FloatingPointError { 2 | 3 | public static void main(String[] args) { 4 | double oneVal = 1.0 / 857.0; 5 | double total = oneVal * 857.0; 6 | boolean areEqual = (total == (double) 1.0); 7 | System.out.println("total = 1.0? " + areEqual); 8 | System.out.println("Why? Because total = " + total); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /sample_code/LinkedList.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | public class LinkedList { 4 | 5 | Node _head = null; 6 | 7 | public LinkedList() { 8 | 9 | } 10 | 11 | public void traverse() { 12 | Node ptr = _head; 13 | while (ptr != null) { 14 | ptr = ptr.getNext(); 15 | } 16 | } 17 | 18 | public void prettyPrint() { 19 | Node ptr = _head; 20 | if (_head == null) { 21 | System.out.println(""); 22 | } 23 | while (ptr != null) { 24 | if (ptr.getNext() != null) { 25 | System.out.print(ptr.getData() + " -> "); 26 | } else { 27 | System.out.println(ptr.getData()); 28 | } 29 | ptr = ptr.getNext(); 30 | } 31 | } 32 | 33 | public void addToFront(Node toAdd) { 34 | if (_head == null) { 35 | _head = toAdd; 36 | } else { 37 | Node oldHead = _head; 38 | _head = toAdd; 39 | _head.setNext(oldHead); 40 | } 41 | } 42 | 43 | public void deleteLast() { 44 | if (_head == null) { 45 | // Nothing to do! 46 | return; 47 | } 48 | 49 | if (_head.getNext() == null) { 50 | _head = null; 51 | return; 52 | } 53 | 54 | Node ptr = _head; 55 | Node last = ptr; 56 | 57 | while (ptr != null) { 58 | 59 | ptr = ptr.getNext(); 60 | if (ptr != null && ptr.getNext() != null) { 61 | 62 | last = ptr; 63 | } 64 | } 65 | 66 | last.setNext(null); 67 | } 68 | 69 | public void deleteFront() { 70 | if (_head == null) { 71 | // Nothing to do! 72 | return; 73 | } 74 | 75 | if (_head.getNext() == null) { 76 | _head = null; 77 | return; 78 | } 79 | 80 | _head = _head.getNext(); 81 | 82 | } 83 | 84 | public T getFrontData() { 85 | if (_head == null) { 86 | return null; 87 | } else { 88 | return _head.getData(); 89 | } 90 | } 91 | 92 | public Node getFront() { 93 | return _head; 94 | } 95 | 96 | public void addToEnd(Node toAdd) { 97 | 98 | toAdd.setNext(null); 99 | 100 | if (_head == null) { 101 | _head = toAdd; 102 | } else { 103 | 104 | Node ptr = _head; 105 | Node last = ptr; 106 | while (ptr != null) { 107 | 108 | last = ptr; 109 | ptr = ptr.getNext(); 110 | } 111 | 112 | last.setNext(toAdd); 113 | 114 | } 115 | 116 | } 117 | 118 | /** 119 | * Delete all duplicate data 120 | */ 121 | 122 | public void deleteDupes() { 123 | 124 | // If there are zero or one elements, there can't be dupes 125 | 126 | if (_head == null || _head.getNext() == null) { 127 | return; 128 | } 129 | 130 | ArrayList prevObjs = new ArrayList(); 131 | Node ptr = _head; 132 | Node last = ptr; 133 | 134 | // Traverse list 135 | 136 | while (ptr != null) { 137 | if (prevObjs.contains(ptr.getData())) { 138 | // delete node - note this will never occur on first pass-through 139 | last.setNext(ptr.getNext()); 140 | } else { 141 | // add it to the list of previous data elements 142 | last = ptr; 143 | prevObjs.add(ptr.getData()); 144 | } 145 | 146 | ptr = ptr.getNext(); 147 | } 148 | 149 | } 150 | 151 | /** 152 | * Will delete first element with that value 153 | * @param valToCheck 154 | */ 155 | 156 | public void deleteByVal(T valToCheck) { 157 | 158 | if (_head == null) { 159 | // nothing here, return 160 | return; 161 | } 162 | 163 | if (_head.getNext() == null) { 164 | // Only one item 165 | if (_head.getData() == valToCheck) { 166 | _head = null; 167 | } 168 | return; 169 | } 170 | 171 | if (_head.getData() == valToCheck) { 172 | _head = _head.getNext(); 173 | } 174 | 175 | Node ptr = _head; 176 | Node last = ptr; 177 | boolean foundIt = false; 178 | while (ptr != null && !(foundIt)) { 179 | if (ptr.getData() == valToCheck) { 180 | // Found it! 181 | foundIt = true; 182 | last.setNext(ptr.getNext()); 183 | } else { 184 | last = ptr; 185 | ptr = ptr.getNext(); 186 | } 187 | } 188 | } 189 | 190 | public void clear() { 191 | _head = null; 192 | } 193 | 194 | public T kthToLast(int k) { 195 | 196 | if (_head == null) { 197 | return null; 198 | } 199 | Node ptr = _head; 200 | Node candidate = null; 201 | int ctr = 0; 202 | while (ptr != null) { 203 | 204 | if (ctr == k) { 205 | candidate = _head; 206 | } else if (ctr > k) { 207 | candidate = candidate.getNext(); 208 | } 209 | ctr++; 210 | ptr = ptr.getNext(); 211 | } 212 | if (candidate == null) { 213 | return null; 214 | } else { 215 | return candidate.getData(); 216 | } 217 | } 218 | 219 | @Override 220 | public boolean equals(Object rhs) { 221 | 222 | // Trivial cases - if exact same object, return true, 223 | // if not of correct class or if null, return false 224 | 225 | if (this == rhs) return true; 226 | else if (!(rhs instanceof LinkedList) || rhs == null) return false; 227 | LinkedList other = (LinkedList) rhs; 228 | boolean toReturn = true; 229 | Node ptr1 = this.getFront(); 230 | Node ptr2 = other.getFront(); 231 | boolean cont = true; 232 | while (ptr1 != null && ptr2 != null && cont == true) { 233 | // System.out.println("Ptr1 = " + ptr1.getData() + " / ptr2 = " + ptr2.getData()); 234 | if (ptr1.getData().equals(ptr2.getData())) { 235 | ptr1 = ptr1.getNext(); 236 | ptr2 = ptr2.getNext(); 237 | } else { 238 | // System.out.println("Data not equal, setting to false"); 239 | toReturn = false; 240 | cont = false; 241 | } 242 | } 243 | if (ptr1 == null ^ ptr2 == null) { 244 | // System.out.println("XOR failure - lists are diff sizes"); 245 | toReturn = false; 246 | } 247 | 248 | return toReturn; 249 | } 250 | 251 | @Override 252 | public int hashCode() { 253 | return 1; 254 | } 255 | 256 | 257 | } 258 | -------------------------------------------------------------------------------- /sample_code/LinkedListTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | // You could also do this to make this a little cleaner. 8 | // import static org.mockito.Mockito.*; 9 | 10 | import org.mockito.*; 11 | 12 | public class LinkedListTest { 13 | 14 | @SuppressWarnings("unchecked") 15 | 16 | // Annotated double 17 | 18 | @Mock 19 | LinkedList mockedLinkedList = Mockito.mock(LinkedList.class); 20 | 21 | @Before 22 | public void setUp() throws Exception { 23 | // If you use @Mock, you need to do this 24 | MockitoAnnotations.initMocks(mockedLinkedList); 25 | 26 | } 27 | 28 | @After 29 | public void tearDown() throws Exception { 30 | // any necessary teardown - none needed here 31 | } 32 | 33 | 34 | // -------------------------------------------------------------- 35 | // ZERO-LENGTH TESTS 36 | // -------------------------------------------------------------- 37 | 38 | // Test that a zero-length list will return null if you try to get 39 | // the first element 40 | @Test 41 | public void testZeroList() { 42 | LinkedList ll = new LinkedList(); 43 | ll.clear(); 44 | assertNull(ll.getFront()); 45 | } 46 | 47 | // Test that the .clear() methods works, by first adding an item, and then 48 | // clearing the list. It should be empty (tested by ensuring that 49 | // the first element is null). 50 | @Test 51 | public void testClearedList() { 52 | LinkedList ll = new LinkedList(); 53 | ll.addToFront(new Node(new Integer(7))); 54 | ll.clear(); 55 | assertNull(ll.getFront()); 56 | } 57 | 58 | // This tests whether a multiple item linked lit will 59 | // clear down to zero items when clear method is called. 60 | 61 | @Test 62 | public void testMultiList() { 63 | LinkedList ll = new LinkedList(); 64 | for (int j=0; j < 10; j++) { 65 | ll.addToFront(new Node(new Integer(j))); 66 | } 67 | ll.clear(); 68 | assertNull(ll.getFront()); 69 | } 70 | 71 | // -------------------------------------------------------------- 72 | // ADD TO FRONT TESTS 73 | // -------------------------------------------------------------- 74 | 75 | // Add ten nodes, then add one more (testNode). Check that setNext() has been 76 | // called to the last of the first ten nodes, and that the added 77 | // node testNode is the same as the one that is at the front of the list. 78 | 79 | @SuppressWarnings("unchecked") 80 | @Test 81 | public void testAddToNoItemLL() { 82 | LinkedList ll = new LinkedList(); 83 | Node[] nodes = new Node[10]; 84 | 85 | for (int j = 0; j < 10; j++) { 86 | nodes[j] = Mockito.mock(Node.class); 87 | ll.addToFront(nodes[j]); 88 | } 89 | 90 | Node testNode = Mockito.mock(Node.class); 91 | ll.addToFront(testNode); 92 | Mockito.verify(testNode).setNext(Matchers.eq(nodes[9])); 93 | assertSame(ll.getFront(), testNode); 94 | 95 | } 96 | 97 | // Add only one node, then add one more (testNode). Check that setNext() has been 98 | // called to the original node and that the added 99 | // node testNode is the same as the one that is at the front of the list. 100 | 101 | @SuppressWarnings("unchecked") 102 | @Test 103 | public void testAddToOneItemLL() { 104 | LinkedList ll = new LinkedList(); 105 | Node existingNode = Mockito.mock(Node.class); 106 | Node testNode = Mockito.mock(Node.class); 107 | ll.addToFront(existingNode); 108 | ll.addToFront(testNode); 109 | Mockito.verify(testNode).setNext(Matchers.eq(existingNode)); 110 | assertSame(ll.getFront(), testNode); 111 | } 112 | 113 | // -------------------------------------------------------------- 114 | // DELETE FROM FRONT TESTS 115 | // -------------------------------------------------------------- 116 | 117 | // Check that attempting to delete a node from a Linked List with 118 | // no elements will not throw an error. 119 | 120 | @Test 121 | public void testDeleteFrontNoItem() { 122 | LinkedList ll = new LinkedList(); 123 | ll.deleteFront(); 124 | assertEquals(ll.getFront(), null); 125 | 126 | } 127 | 128 | // Check that deleting a node from a Linked List with 129 | // one elements will not throw an error, and will result in an 130 | // empty LinkedList (front is null). 131 | 132 | @SuppressWarnings("unchecked") 133 | @Test 134 | public void testDeleteFrontOneItem() { 135 | LinkedList ll = new LinkedList(); 136 | ll.addToFront(Mockito.mock(Node.class)); 137 | ll.deleteFront(); 138 | assertEquals(ll.getFront(), null); 139 | } 140 | 141 | // Check that deleting a node from a Linked List with 142 | // multiple elements will properly delete the first node 143 | // and leave the old second node as the new first node.. 144 | 145 | @SuppressWarnings("unchecked") 146 | @Test 147 | public void testDeleteFrontMultipleItems() { 148 | LinkedList ll = new LinkedList(); 149 | Node[] nodes = new Node[10]; 150 | 151 | for (int j = 0; j < 10; j++) { 152 | nodes[j] = new Node(new Integer(1)); 153 | ll.addToFront(nodes[j]); 154 | } 155 | 156 | ll.deleteFront(); 157 | 158 | assertSame(ll.getFront(), nodes[8]); 159 | } 160 | 161 | // -------------------------------------------------------------- 162 | // EQUALITY TESTS 163 | // -------------------------------------------------------------- 164 | 165 | // Check that a new linked list equals itself. 166 | @Test 167 | public void testEqualsSelf() { 168 | LinkedList ll = new LinkedList(); 169 | assertEquals(ll, ll); 170 | } 171 | 172 | // Check that two new linked lists with no elements equal each other. 173 | @Test 174 | public void testEquals0Elems() { 175 | LinkedList ll01 = new LinkedList(); 176 | LinkedList ll02 = new LinkedList(); 177 | assertEquals(ll01, ll02); 178 | } 179 | 180 | // An instantiated linked list should not equal null. 181 | @Test 182 | public void testNotEqualsNull() { 183 | LinkedList ll01 = new LinkedList(); 184 | assertFalse(ll01.equals(null)); 185 | } 186 | 187 | // Check that a LL object does equal a non-LinkedList, e.g. Object 188 | @Test 189 | public void testNotEqualsRegularObject() { 190 | LinkedList ll01 = new LinkedList(); 191 | Object obj = new Object(); 192 | assertFalse(ll01.equals(obj)); 193 | } 194 | 195 | 196 | // Check that two LLs with the same Node value with a single node are equal 197 | @Test 198 | public void testEqualsOneNodeSameVals() { 199 | LinkedList ll11 = new LinkedList(); 200 | LinkedList ll12 = new LinkedList(); 201 | ll11.addToFront(new Node(new Integer(1))); 202 | ll12.addToFront(new Node(new Integer(1))); 203 | assertEquals(ll11, ll12); 204 | } 205 | 206 | // Check that two LL with different Node values with a single node are NOT equal 207 | @Test 208 | public void testEqualsOneNodeDiffVals() { 209 | LinkedList ll11 = new LinkedList(); 210 | LinkedList ll2 = new LinkedList(); 211 | ll11.addToFront(new Node(new Integer(1))); 212 | ll2.addToFront(new Node(new Integer(2))); 213 | assertFalse(ll11.equals(ll2)); 214 | } 215 | 216 | // Check that two LLs with different sizes, but the same front node value, 217 | // are not considered equal. 218 | @Test 219 | public void testNotEqualsDiffSizes() { 220 | LinkedList ll11 = new LinkedList(); 221 | LinkedList ll_3elems = new LinkedList(); 222 | 223 | ll11.addToFront(new Node(new Integer(1))); 224 | ll_3elems.addToFront(new Node(new Integer(3))); 225 | ll_3elems.addToFront(new Node(new Integer(2))); 226 | ll_3elems.addToFront(new Node(new Integer(1))); 227 | 228 | assertFalse(ll_3elems.equals(ll11)); 229 | } 230 | 231 | // Check that a LL which is just a reference to another instance of itself 232 | // equals itself 233 | @Test 234 | public void testEqualsRef() { 235 | LinkedList ll11 = new LinkedList(); 236 | ll11.addToFront(new Node(new Integer(1))); 237 | LinkedList ll11_new = ll11; 238 | assertSame(ll11, ll11_new); 239 | } 240 | 241 | // Check that LLs with the same size, but different data in the nodes, 242 | // do not equal each other. 243 | @Test 244 | public void testNotEqualsDiffData() { 245 | LinkedList ll_3elems = new LinkedList(); 246 | LinkedList ll_321 = new LinkedList(); 247 | ll_3elems.addToFront(new Node(new Integer(3))); 248 | ll_3elems.addToFront(new Node(new Integer(2))); 249 | ll_3elems.addToFront(new Node(new Integer(1))); 250 | 251 | ll_321.addToFront(new Node(new Integer(1))); 252 | ll_321.addToFront(new Node(new Integer(2))); 253 | ll_321.addToFront(new Node(new Integer(3))); 254 | assertFalse(ll_321.equals(ll_3elems)); 255 | } 256 | 257 | // Check that two multiple-node LLs with the same data equal each other 258 | @Test 259 | public void testEqualsSameData() { 260 | LinkedList ll_321 = new LinkedList(); 261 | LinkedList ll_321_2 = new LinkedList(); 262 | 263 | ll_321.addToFront(new Node(new Integer(1))); 264 | ll_321.addToFront(new Node(new Integer(2))); 265 | ll_321.addToFront(new Node(new Integer(3))); 266 | 267 | ll_321_2.addToFront(new Node(new Integer(1))); 268 | ll_321_2.addToFront(new Node(new Integer(2))); 269 | ll_321_2.addToFront(new Node(new Integer(3))); 270 | 271 | assertTrue(ll_321.equals(ll_321_2)); 272 | 273 | } 274 | 275 | } 276 | -------------------------------------------------------------------------------- /sample_code/Node.java: -------------------------------------------------------------------------------- 1 | public class Node { 2 | 3 | private Node _nextNode = null; 4 | private T _data = null; 5 | 6 | public Node(T data) { 7 | _data = data; 8 | } 9 | 10 | public void setData(T data) { 11 | _data = data; 12 | } 13 | 14 | public T getData() { 15 | return _data; 16 | } 17 | 18 | public Node getNext() { 19 | return _nextNode; 20 | } 21 | 22 | public void setNext(Node newNext) { 23 | _nextNode = newNext; 24 | } 25 | 26 | public String toString() { 27 | if (_nextNode != null) { 28 | return "(" + _data + ", " + _nextNode.hashCode() + ")"; 29 | } else { 30 | return "(" + _data + ", " + null + ")"; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample_code/TestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class TestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(LinkedListTest.class); 15 | 16 | // For all test classes added, loop through and use JUnit 17 | // to run them. 18 | 19 | for (Class c: classesToTest) { 20 | Result r = JUnitCore.runClasses(c); 21 | 22 | // Print out any failures for this class. 23 | 24 | for (Failure f : r.getFailures()) { 25 | System.out.println(f.toString()); 26 | } 27 | 28 | // If r is not successful, there was at least one 29 | // failure. Thus, set anyFailures to true - this 30 | // can never be set back to false (no amount of 31 | // successes will ever eclipse the fact that there 32 | // was at least one failure. 33 | 34 | if (!r.wasSuccessful()) { 35 | anyFailures = true; 36 | } 37 | 38 | } 39 | 40 | // After completion, notify user if all tests passed or any failed. 41 | 42 | if (anyFailures) { 43 | System.out.println("\n!!! - At least one failure, see above."); 44 | } else { 45 | System.out.println("\nALL TESTS PASSED"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample_code/heartbleed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void bad(int len) { 6 | char* notSecret = "open data"; 7 | char* secret = "SECRET DATA HERE! NOBODY SHOULD SEE THIS!"; 8 | printf("Sending data:\n"); 9 | for (int j=0; j < len; j++) { 10 | printf("%d: %c\n", j, notSecret[j]); 11 | } 12 | 13 | } 14 | 15 | int main() { 16 | int l; 17 | puts("Enter length of data:"); 18 | scanf("%d", &l); 19 | bad(l); 20 | puts(""); 21 | } 22 | -------------------------------------------------------------------------------- /sample_code/runTests.sh: -------------------------------------------------------------------------------- 1 | javac -cp .:..:./CommandLineJunit/hamcrest-core-1.3.jar:./CommandLineJunit/junit-4.12.jar:./CommandLineJunit/mockito-core-1.10.19.jar:./CommandLineJunit/objenesis-2.4.jar *.java 2 | 3 | java -cp .:..:./CommandLineJunit/hamcrest-core-1.3.jar:./CommandLineJunit/junit-4.12.jar:./CommandLineJunit/mockito-core-1.10.19.jar:./CommandLineJunit/objenesis-2.4.jar TestRunner 4 | -------------------------------------------------------------------------------- /sample_code/selenium_example/README.md: -------------------------------------------------------------------------------- 1 | 1. Ensure you have downloaded all four of the selenium and junit jars (now included in the repo). 2 | 2. Compile with the following command: `javac -cp .:./junit-4.12.jar:./hamcrest-core-1.3.jar:./selenium-java-2.52.0.jar:./selenium-server-standalone-2.52.0.jar *.java`. Remember to replace :'s with ;'s if you are using Windows. If you are using Windows 7 you may need to put the classpath string (everywhere from the first `.` to the last `.jar`) in double quotes. Also note that you must ensure that your paths do not include any ~s, wildcards, or other shell-expanding characters (if in doubt, make absolute paths). javac will not expand these. 3 | 3. Run with the following command: `java -cp .:./junit-4.12.jar:./hamcrest-core-1.3.jar:./selenium-java-2.52.0.jar:./selenium-server-standalone-2.52.0.jar RedditTestRunner` You should see no test failures. 4 | 4. Note, however, you will see many INFO-level warnings. These can safely be ignored. Run RedditTestRunnerNoLogs.java to run an equivalent test without the superfluous logging. 5 | -------------------------------------------------------------------------------- /sample_code/selenium_example/RedditTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | import org.openqa.selenium.*; 6 | import org.openqa.selenium.firefox.FirefoxDriver; 7 | import org.openqa.selenium.htmlunit.HtmlUnitDriver; 8 | 9 | /** 10 | * As a user, 11 | * I would like to see reddit links in all sorts of ways, 12 | * So that I can know what is happening in the world 13 | * @author wlaboon 14 | * 15 | */ 16 | 17 | public class RedditTest { 18 | 19 | static WebDriver driver = new HtmlUnitDriver(); 20 | 21 | // Start at the home page for reddit for each test 22 | @Before 23 | public void setUp() throws Exception { 24 | driver.get("https://www.reddit.com"); 25 | } 26 | 27 | // Given that I am on the main page 28 | // When I view the title 29 | // Then I see that it contains the word "reddit" 30 | @Test 31 | public void testShowsCorrectTitle() { 32 | 33 | // Simply check that the title contains the word "reddit" 34 | 35 | String title = driver.getTitle(); 36 | assertTrue(title.contains("reddit")); 37 | } 38 | 39 | // Given that I am on the main page 40 | // When I view the header 41 | // Then I see that it contains "new", "rising", and "top" links 42 | @Test 43 | public void testHasCorrectHeaderLinks() { 44 | 45 | // Check for new, rising, and top links - if any of 46 | // these is not found, fail the test 47 | 48 | try { 49 | driver.findElement(By.linkText("new")); 50 | driver.findElement(By.linkText("rising")); 51 | driver.findElement(By.linkText("top")); 52 | } catch (NoSuchElementException nseex) { 53 | fail(); 54 | } 55 | } 56 | 57 | // Given that I am on the main page 58 | // When I view the Remember Me section 59 | // Then I should see that it contains the phrase "remember me" 60 | @Test 61 | public void testHasRememberMe() { 62 | 63 | // Check that there is a remember-me element 64 | // that contains the text "remember me" 65 | // If it does not exist, or text is incorrect, fail test 66 | 67 | try { 68 | WebElement e = driver.findElement(By.id("remember-me")); 69 | String elementText = e.getText(); 70 | assertTrue(elementText.contains("remember me")); 71 | } catch (NoSuchElementException nseex) { 72 | fail(); 73 | } 74 | } 75 | 76 | // Given that I am on the main page 77 | // When I click on the "new" link 78 | // Then I should be redirected to the "new" page 79 | @Test 80 | public void testSeeNewLinks() { 81 | 82 | // find the "new" link and click on it 83 | // The page you go to should include "newest submissions" 84 | // in the title 85 | 86 | driver.findElement(By.linkText("new")).click(); 87 | String newPageTitle = driver.getTitle(); 88 | assertTrue(newPageTitle.contains("newest submissions")); 89 | } 90 | 91 | // Given that I am on the main page 92 | // And I am not logged in 93 | // When I try to login with an valid username and invalid password 94 | // Then I am given the opportunity to reset the password 95 | @Test 96 | public void testBadPasswordResetLink() { 97 | 98 | // Enter username "meow", password "meow" 99 | 100 | // ENTER YOUR OWN USERNAME/INVALID PASSWORD HERE! 101 | 102 | // driver.findElement(By.name("user")).sendKeys("dasbill"); 103 | // driver.findElement(By.name("passwd")).sendKeys("meow"); 104 | 105 | // Look for the submit button (in the login div) and click 106 | // to attempt to login 107 | 108 | WebElement loginDiv = driver.findElement(By.id("login_login-main")); 109 | 110 | WebElement submitButton = loginDiv.findElement(By.className("btn")); 111 | submitButton.click(); 112 | 113 | // Check that there is a link to reset password and it is visible 114 | 115 | try { 116 | WebElement resetPw = driver.findElement(By.linkText("reset password")); 117 | assertTrue(resetPw.isDisplayed()); 118 | } catch (NoSuchElementException nseex) { 119 | fail(); 120 | } 121 | } 122 | 123 | 124 | } 125 | -------------------------------------------------------------------------------- /sample_code/selenium_example/RedditTestNoLogs.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import java.util.logging.*; 4 | 5 | import org.junit.*; 6 | import org.openqa.selenium.*; 7 | 8 | import org.openqa.selenium.firefox.FirefoxDriver; 9 | import org.openqa.selenium.htmlunit.HtmlUnitDriver; 10 | 11 | import org.openqa.selenium.logging.*; 12 | 13 | import org.openqa.selenium.remote.*; 14 | 15 | /** 16 | * As a user, 17 | * I would like to see reddit links in all sorts of ways, 18 | * So that I can know what is happening in the world 19 | * @author wlaboon 20 | * 21 | */ 22 | 23 | public class RedditTestNoLogs { 24 | 25 | static WebDriver driver; 26 | 27 | // Note that the @BeforeClass annotation runs ONCE 28 | // per class, before any of the test cases are run 29 | // Compare this to @Before, which runs before 30 | // EACH @Test-annotated method (test case) 31 | 32 | @BeforeClass 33 | public static void setUpDriver() { 34 | 35 | // Note that the logging level is a Java standard (thus the 36 | // use of a java.util class instead of something specific 37 | // to Selenium. You can modify these levels yourself if, 38 | // for example, you would like to see only SEVERE errors. 39 | // They can be set to ALL (show all messages) or OFF (no messages) 40 | // or to any minimum level from FINEST (most verbose) to SEVERE 41 | // (only show the most egregious of errors). 42 | // A full lists of levels and descriptions are located at: 43 | // https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html 44 | 45 | java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF); 46 | System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); 47 | driver = new HtmlUnitDriver(); 48 | 49 | } 50 | 51 | 52 | // Start at the home page for reddit for each test 53 | @Before 54 | public void setUp() throws Exception { 55 | driver.get("https://www.reddit.com"); 56 | } 57 | 58 | // Given that I am on the main page 59 | // When I view the title 60 | // Then I see that it contains the word "reddit" 61 | @Test 62 | public void testShowsCorrectTitle() { 63 | 64 | // Simply check that the title contains the word "reddit" 65 | 66 | String title = driver.getTitle(); 67 | assertTrue(title.contains("reddit")); 68 | } 69 | 70 | // Given that I am on the main page 71 | // When I view the header 72 | // Then I see that it contains "new", "rising", and "top" links 73 | @Test 74 | public void testHasCorrectHeaderLinks() { 75 | 76 | // Check for new, rising, and top links - if any of 77 | // these is not found, fail the test 78 | 79 | try { 80 | driver.findElement(By.linkText("new")); 81 | driver.findElement(By.linkText("rising")); 82 | driver.findElement(By.linkText("top")); 83 | } catch (NoSuchElementException nseex) { 84 | fail(); 85 | } 86 | } 87 | 88 | // Given that I am on the main page 89 | // When I view the Remember Me section 90 | // Then I should see that it contains the phrase "remember me" 91 | @Test 92 | public void testHasRememberMe() { 93 | 94 | // Check that there is a remember-me element 95 | // that contains the text "remember me" 96 | // If it does not exist, or text is incorrect, fail test 97 | 98 | try { 99 | WebElement e = driver.findElement(By.id("remember-me")); 100 | String elementText = e.getText(); 101 | assertTrue(elementText.contains("remember me")); 102 | } catch (NoSuchElementException nseex) { 103 | fail(); 104 | } 105 | } 106 | 107 | // Given that I am on the main page 108 | // When I click on the "new" link 109 | // Then I should be redirected to the "new" page 110 | @Test 111 | public void testSeeNewLinks() { 112 | 113 | // find the "new" link and click on it 114 | // The page you go to should include "newest submissions" 115 | // in the title 116 | 117 | driver.findElement(By.linkText("new")).click(); 118 | String newPageTitle = driver.getTitle(); 119 | assertTrue(newPageTitle.contains("newest submissions")); 120 | } 121 | 122 | // Given that I am on the main page 123 | // And I am not logged in 124 | // When I try to login with an valid username and invalid password 125 | // Then I am given the opportunity to reset the password 126 | @Test 127 | public void testBadPasswordResetLink() { 128 | 129 | // Enter username "meow", password "meow" 130 | 131 | driver.findElement(By.name("user")).sendKeys("dasbill"); 132 | driver.findElement(By.name("passwd")).sendKeys("meow"); 133 | 134 | // Look for the submit button (in the login div) and click 135 | // to attempt to login 136 | 137 | WebElement loginDiv = driver.findElement(By.id("login_login-main")); 138 | 139 | WebElement submitButton = loginDiv.findElement(By.className("btn")); 140 | submitButton.click(); 141 | 142 | // Check that there is a link to reset password and it is visible 143 | 144 | try { 145 | WebElement resetPw = driver.findElement(By.linkText("reset password")); 146 | assertTrue(resetPw.isDisplayed()); 147 | } catch (NoSuchElementException nseex) { 148 | fail(); 149 | } 150 | } 151 | 152 | 153 | } 154 | -------------------------------------------------------------------------------- /sample_code/selenium_example/RedditTestRunner.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class RedditTestRunner { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(RedditTest.class); 15 | 16 | // For all test classes added, loop through and use JUnit 17 | // to run them. 18 | 19 | for (Class c: classesToTest) { 20 | Result r = JUnitCore.runClasses(c); 21 | 22 | // Print out any failures for this class. 23 | 24 | for (Failure f : r.getFailures()) { 25 | System.out.println(f.toString()); 26 | } 27 | 28 | // If r is not successful, there was at least one 29 | // failure. Thus, set anyFailures to true - this 30 | // can never be set back to false (no amount of 31 | // successes will ever eclipse the fact that there 32 | // was at least one failure. 33 | 34 | if (!r.wasSuccessful()) { 35 | anyFailures = true; 36 | } 37 | 38 | } 39 | 40 | // After completion, notify user if all tests passed or any failed. 41 | 42 | if (anyFailures) { 43 | System.out.println("\n!!! - At least one failure, see above."); 44 | } else { 45 | System.out.println("\nALL TESTS PASSED"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample_code/selenium_example/RedditTestRunnerNoLogs.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | 3 | import org.junit.runner.*; 4 | import org.junit.runner.notification.*; 5 | 6 | public class RedditTestRunnerNoLogs { 7 | public static void main(String[] args) { 8 | 9 | ArrayList classesToTest = new ArrayList(); 10 | boolean anyFailures = false; 11 | 12 | // ADD ANY MORE CLASSES YOU WISH TO TEST HERE 13 | 14 | classesToTest.add(RedditTestNoLogs.class); 15 | 16 | // For all test classes added, loop through and use JUnit 17 | // to run them. 18 | 19 | for (Class c: classesToTest) { 20 | Result r = JUnitCore.runClasses(c); 21 | 22 | // Print out any failures for this class. 23 | 24 | for (Failure f : r.getFailures()) { 25 | System.out.println(f.toString()); 26 | } 27 | 28 | // If r is not successful, there was at least one 29 | // failure. Thus, set anyFailures to true - this 30 | // can never be set back to false (no amount of 31 | // successes will ever eclipse the fact that there 32 | // was at least one failure. 33 | 34 | if (!r.wasSuccessful()) { 35 | anyFailures = true; 36 | } 37 | 38 | } 39 | 40 | // After completion, notify user if all tests passed or any failed. 41 | 42 | if (anyFailures) { 43 | System.out.println("\n!!! - At least one failure, see above."); 44 | } else { 45 | System.out.println("\nALL TESTS PASSED"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample_code/selenium_example/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/selenium_example/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /sample_code/selenium_example/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/selenium_example/junit-4.12.jar -------------------------------------------------------------------------------- /sample_code/selenium_example/run.sh: -------------------------------------------------------------------------------- 1 | javac -cp .:selenium-java-2.52.0.jar:selenium-server-standalone-2.52.0.jar:hamcrest-core-1.3.jar:junit-4.12.jar *.java 2 | 3 | java -cp .:selenium-java-2.52.0.jar:selenium-server-standalone-2.52.0.jar:hamcrest-core-1.3.jar:junit-4.12.jar RedditTestRunner 4 | -------------------------------------------------------------------------------- /sample_code/selenium_example/selenium-java-2.52.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/selenium_example/selenium-java-2.52.0.jar -------------------------------------------------------------------------------- /sample_code/selenium_example/selenium-server-standalone-2.52.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laboon/CS1632_Fall2017/03a39ac948f02bd7608e93806c48aab738e96006/sample_code/selenium_example/selenium-server-standalone-2.52.0.jar -------------------------------------------------------------------------------- /study_guides/midterm_1_study_guide.md: -------------------------------------------------------------------------------- 1 | # CS 1632 Midterm 1 Exam Study Guide - Fall 2017 2 | 3 | The midterm is on 11 OCT 2017. 4 | 5 | The midterm will cover everything we have covered up to the exerise on 4 OCT (i.e., nothing from the combinatorial testing lecture on 10 OCT will be included). I recommend you review the slides and the textbook (see syllabus.md for reminders of which chapters were required reading). 6 | 7 | However, here are the key topics to study in preparation for the test. 8 | 9 | ## TESTING THEORY AND TERMINOLOGY 10 | * Equivalence class partitioning 11 | * Boundary and interior values 12 | * Base, Edge, and Corner cases 13 | * Static vs Dynamic testing 14 | * Know the differences and examples of each 15 | * Black/White/Grey box testing 16 | * Know the differences and examples of each 17 | 18 | ## REQUIREMENTS ANALYSIS 19 | * What makes a good or bad requirement? 20 | * Testability - requirements must be: 21 | * Complete, consistent, unambiguous, quantitative, feasible 22 | * Functional Requirements vs Non-Functional (Quality Attributes) 23 | * Be able to define and write your own 24 | * Traceability Matrices 25 | * Be able to define and write your own 26 | 27 | ## TEST PLANS 28 | * Given a list of requirements, be able to write a test plan 29 | * Terminology: test cases, test plans, test suites, test runs 30 | * Verification vs validation 31 | 32 | ## DEFECT REPORTING 33 | * Be prepared to report a defect based on a test case 34 | * Remember the defect template: 35 | * SUMMARY, DESCRIPTION, REPRODUCTION STEPS, EXPECTED BEHAVIOR, OBSERVED BEHAVIOR 36 | * Optionally: SEVERITY/IMPACT, NOTES 37 | * Levels of severity: BLOCKER, CRITICAL, MAJOR, NORMAL, MINOR, TRIVIAL 38 | * Enhancements vs defects 39 | * Be prepared to argue if something is a defect or enhancement 40 | * Coding mistakes vs defects 41 | 42 | ## AUTOMATED TESTING 43 | * Pros and cons of automated testing 44 | * Unit tests vs system/acceptance/integration tests 45 | * Writing automated tests: 46 | * PRECONDITIONS, POSTCONDITIONS, EXECUTION STEPS, INPUT/OUTPUT VALUES 47 | 48 | ## UNIT TESTING 49 | * Be prepared to write some unit tests in JUnit 50 | * Pay special attention to assertions 51 | * Stubs, test doubles, mocks, and verification 52 | * Testing private methods 53 | * You will NOT need to use/know about reflection 54 | * Why/why not one might not test them? 55 | 56 | ## BREAKING SOFTWARE 57 | * Be prepared to think of happy path vs edge case testing 58 | * What are various ways that software can break? 59 | 60 | ## TDD 61 | * The red-green-refactor loop 62 | * Principles of TDD: 63 | * YAGNI 64 | * KISS 65 | * "Fake it 'til you make it" 66 | * Avoid interdependency 67 | * Avoid slow tests 68 | * Benefits and drawbacks of TDD 69 | * When to use it? 70 | * When not to use it? 71 | 72 | ## WRITING TESTABLE CODE 73 | * Basic strategies for testable code 74 | * The DRY Principle 75 | * The Law of Demeter 76 | * TUFs and TUCs 77 | 78 | -------------------------------------------------------------------------------- /study_guides/midterm_2_study_guide.md: -------------------------------------------------------------------------------- 1 | # CS 1632 Midterm 2 Study Guide 2 | FALL 2017 3 | 4 | The second midterm is WEDNESDAY 29 NOV. 5 | 6 | Note that the second midterm is _not_ cumulative, except in the sense that the topics covered in the second half of the semester depend on understanding of the more fundamental concepts taught in the beginning of the course. 7 | 8 | ## COMBINATORIAL TESTING 9 | * Benefits / Drawbacks 10 | * Given a problem, be able to make a truth table 11 | * Understand what a covering array is 12 | * Be able to make a simple covering array 13 | * Be able to determine what pairs are not being tested by a covering array 14 | 15 | ## WEB TESTING 16 | * Be able to explain how you would test a web page with Selenium 17 | * Understand how you should NOT test a web page 18 | * Understand possible problems with testing a web page 19 | * You do NOT need to know Selenese (Selenium scripting language) 20 | * Understand basic usage of Selenium with JUnit (driver, WebElement, etc.) 21 | 22 | ## PROPERTY-BASED TESTING 23 | * Be able to write simple property-based tests 24 | * Be able to name invariants given a function and sample input/output 25 | * Be able to show how invariants are broken 26 | * Understand what shrinking is and be able to provide an example 27 | * What is property-based testing good for? What is it bad for? 28 | 29 | ## PERFORMANCE TESTING 30 | * Understand concepts on how to test performance 31 | * Be able to write test plans for different performance indicators and systems 32 | * Terminology: Service-Oriented vs Efficiency-Oriented Indicators 33 | * Availability, Response Time, Throughput, Utilization 34 | * Performance targets, performance thresholds, KPIs - understand and be able to generate! 35 | * Measuring response time - methodologies 36 | * Understand different concepts of time: user, system, total, real 37 | * Measuring availability, concurrency, scalability, throughput 38 | * Understand n 9's (e.g., 5 9s vs 6 9s) 39 | * Load testing - baseline, soak/stability, stress tests 40 | * When to use a profiler 41 | 42 | ## STATIC ANALYSIS 43 | * Understand static vs dynamic testing 44 | * Understand limitations of static testing 45 | * Know different kinds of static analysis, and tools and methods used (e.g. linters, bug finders, code coverage, code metrics, code reviews) 46 | 47 | ## INTERACTING WITH STAKEHOLDERS 48 | * Be able to name some stakeholders and what is important to them (upper management, project management, testers, other developers) 49 | * Be prepared for some "fake" interaction with various stakeholders 50 | * Be able to put together a red-yellow-green template report 51 | 52 | ## Testing Strategy 53 | * Understand the testing pyramid 54 | * Understand common anti-patterns (ice cream cone, cupcake) 55 | * Given a description of a program, be able to develop your own testing strategy 56 | -------------------------------------------------------------------------------- /syllabus.md: -------------------------------------------------------------------------------- 1 | # Syllabus - Fall 2017 2 | CS1632 Software Quality Assurance 3 | 4 | _Although the professor will make a best effort to have the class topic on the day listed, occasionally a change must be made (e.g., a lecture going long, or a guest lecturer unable to make it to class that day). However, these are the topics that will be covered and the expected date that they will be taught._ 5 | 6 | AFIST = _A Friendly Introduction to Software Testing_ by Bill Laboon 7 | 8 | ## WEEK 1 (28 and 30 Aug) 9 | * (28 Aug) Introduction - What is Software Quality Assurance? 10 | 11 | * (30 Aug) Basic Testing Theory and Terminology 12 | * READING: AFIST, Chapters 2 - 4 13 | 14 | ## WEEK 2 (4 and 6 Sep) 15 | 16 | * (4 Sep) NO CLASS - LABOR DAY 17 | 18 | * (6 Sep) Requirements and Defects 19 | * READING: AFIST, Chapters 5 and 9 20 | 21 | ## WEEK 3 (11 and 13 Sep) 22 | 23 | * (11 Sep) Test Plans and Breaking Software 24 | 25 | * (13 Sep) EX1: Test Plans 26 | 27 | Exploratory Testing 28 | 29 | ## WEEK 4 (18 and 20 Sep) 30 | 31 | * (18 Sep) Automated and Manual Testing, Unit Testing Part 1 32 | * READING: AFIST, Chapter 12-13 33 | 34 | * (20 Sep) Unit Testing Part 2 35 | * READING: AFIST, Chapter 14 36 | 37 | ## WEEK 5 (25 and 27 Sep) 38 | 39 | * (25 Sep) EX2: Unit Testing 40 | 41 | * (27 Sep) Test-driven Development 42 | * READING: AFIST, Chapter 15 43 | 44 | ## WEEK 6 (2 and 4 Oct) 45 | 46 | * (2 Oct) Writing Testable Code 47 | * READING: AFIST, Chapter 16 48 | 49 | * (4 Oct) EX3: Unit Testing and TDD 50 | 51 | ## WEEK 7 (10 and 11 Oct) 52 | 53 | _Note: Classes that are normally held on Monday are shifted to Tuesday on this week due to the Monday holiday._ 54 | 55 | * (10 Oct) Pairwise and Combinatorial Testing 56 | * READING: AFIST, Chapter 17 57 | 58 | * (11 Oct) MIDTERM 1 59 | 60 | ## WEEK 8 (16 and 18 Oct) 61 | 62 | * (16 Oct) Automated System Testing 63 | 64 | * (18 Oct) Automated System Testing, Part 2 65 | 66 | ## WEEK 9 (23 and 25 Oct) 67 | 68 | * (23 Oct) EX4: Automated System Testing 69 | 70 | * (25 Oct) Performance Testing, Part 1 71 | * READING: AFIST, Chapter 19 72 | 73 | ## WEEK 10 (30 Oct and 1 Nov) 74 | 75 | * (30 Oct) Performance Testing, Part 2 76 | 77 | * (1 Nov) EX5: Performance Testing 78 | 79 | ## WEEK 11 (6 and 8 Nov) 80 | 81 | * (6 Nov) Static Analysis, Part 1 82 | 83 | * (8 Nov) Static Analysis, Part 2 84 | 85 | ## WEEK 12 (13 and 15 Nov) 86 | 87 | * (13 Nov) EX6: Static Analysis 88 | 89 | * (15 Nov) Developing and Managing a Testing Strategy 90 | 91 | ## WEEK 13 (20 and 22 Nov) 92 | 93 | * (20 Nov) Stochastic and Property-Based Testing 94 | * READING: AFIST, Chapter 18 95 | 96 | * (22 Nov) NO CLASS 97 | 98 | ## WEEK 14 (30 Nov and 1 Dec) 99 | 100 | * (27 Nov) Interacting With Stakeholders 101 | * READING: AFIST, Chapter 21 102 | 103 | * (29 Nov) MIDTERM 2 104 | 105 | ## WEEK 15 (6 and 8 Dec) 106 | 107 | * (4 Dec) Security Testing 108 | * READING: AFIST, Chapter 20 109 | 110 | * (6 Dec) EX7: Penetration Testing 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | --------------------------------------------------------------------------------