Final Exam Study Guide Part 2 PDF
Document Details
Uploaded by ResourcefulFuturism3119
Saint Vincent College
Tags
Summary
This document provides a study guide for a course's final exam. It covers topics like software architecture, architectural patterns, and integration testing. Focus is on software engineering concepts.
Full Transcript
Second Half of the Semester Software Architecture What does "architecture" mean in the context of software engineering? It's similar to a design pattern as in its a general framework/approach to building a software product. What is the difference between a component and a module?...
Second Half of the Semester Software Architecture What does "architecture" mean in the context of software engineering? It's similar to a design pattern as in its a general framework/approach to building a software product. What is the difference between a component and a module? Modules are generally smaller, components are generally bigger. A function is a module, if it's part of class its likely that the class is a module. If there's a collection of 5 modules that probably forms a component. Components -> high level and Modules -> low level. Architectural Patterns to be broadly familiar with. What is the Client-Server architectural pattern? Two separate components that communicate with each other, can often be done with two separate code bases. The server is centralized and the client can operate on many different devices, clients cannot communicate with each other, but instead communicate through the server. What is the different between client-side and server-side? Client-side code runs on the client's device, whereas server-side code is run remotely on the server and the results if any are sent to the client for display. What is the Three-Layer Architecture? It consists of a Presentation layer, a Business Logic layer, and the Data Layer in order from top to bottom. It's also similar to a layered architecture in that each layer is a service to the layer above and a client to the layer below. Presentation This layer handles serving information or any service to the end-user. Examples of a presentation layer include a GUI, an API, or a CLI. Business Logic Layer The business logic layer enforces real world rules. For example it might check that a student meets prerequisites before enrolling them in a course, or enforcing deadlines in a submission system. Data Layer How and where is data stored? The answer to that question is the data layer. It could be anything from a big.csv file to a proper database server like MySQL or PostgreSQL. What is the MVC architecture? MVC or Model, View, Controller is very similar to the three-layer architecture. It consists of a View layer, a Model Layer, and a Controller layer. it differs slightly from the three layer architecture in that model is analogous to the Data Layer and Business Logic layer. The controller may handle very limited business logic, but its generally focused with controlling the UI because it's so tightly coupled with the View. Compare Monolith vs. Micro-service. Monolith Monolith as an architecture is just having all code be in the same image and deployed as a single application. It offers many advantages over the micro-service architecture including ease of debugging, lower server costs, ease of scaling the entire application, and ease of deploying updates. However, it becomes difficult to change design decisions and its much harder to update, maintain, and fix as the scale of the application grows. Microservice Microservices as an architecture is separating code into smaller, independent services. Then each microservice interacts with each other over the web. Essentially everything is designed as if its externally facing. This makes it much easier to scale individual services as needed, and it also makes maintaining the system easier. However, it often leads to higher server costs, difficult debugging, performance loss on indirection, and difficult logging/monitoring. Integration Testing How is integration testing different from unit and system testing? Unit testing tests an individual unit of the system and system testing tests the combination of the entire program as a whole. Integration testing is a middle-ground that tests smaller combinations of the units. Strategies What is Big-Bang integration testing? What are some pros and cons? A strategy of integration testing that involves throwing things together haphazardly without thought. Pros Easy. Cons Hard to trace faults. Infeasible with larger, more complex codebases. What is Top-Down integration testing? What are some pros and cons? In Top-Down integration testing you start with the modules on which nothing else depends (stuff like view, presentation layer) and integrate with only the modules that they depend on. Then starting from those modules you continue the chain. Pros Easiest for prototyping (because you build a GUI/working application with fake data). Naturally lends itself to patterns of abstraction. Helps you focus more on the higher-level design decisions and modify lower-levels to acomodate the higher levels Makes you define a dependency's interface before implementation. Cons Need to add stubs/mock data. The least tested code is the most low-level data-intensive code. You often start with one of the hardest layers (presentation/view/GUI). What is Bottom-Up integration testing? What are some pros and cons? In Bottom-Up integration testing you start with modules that have no dependencies (usually low-level stuff like IO, Databases, Files). Then you only integrate modules that depend on your starting module. Finally, starting from those modules you continue the chain. Pros Easier to trace fault responsibility. Integrate as you build, no need for mocks you can use the real code. If low-level code is where the bulk of difficulty is, you spend the most time testing it. Cons It's complex. It goes against the natural patterns of abstractions (you start with the implementation before thinking about the interface). Implementing the high level classes (which have the greatest impact on your project) after the lowest level can lead to bad design choices. Impossible to build effective prototypes quickly. What is Sandwich integration testing? What are some pros and cons? Start with a middle layer and use the bottom-up approach for the layers above and a top-down approach for the layers below. Pros Combines the advantages of Top-Down and Bottom-Up Great for complex systems. Cons Difficult to implement, requires a lot of skill sets. There's often not a clear "middle" layer which makes it difficult to use the sandwich strategy. What are Stubs, and how do they relate to integration testing? Stubs are used to replace incomplete modules or unavailable modules in integration testing. A stub simulates the module's outputs without necessarily maintaining its internal states. What are Drivers, and how do they relate to integration testing? Drivers are used when the encapsulating module that calls a lower level is unavailable/missing. Consider an application that reads data from a file and then prints it to stdout. If we have a bunch of code that reads data, we can't test it without calling the functions in the code. In your final program, it's likely your upper level (the level that prints to stdout) that calls these functions. However, when testing we might not be able to use the upper level, so we can use a driver to replace it. Mockito What does the @Mock annotation do? It allows you to define mock objects as instance variables. What does mock(ClassName.class) do It allows you to define mock objects on the fly for use in unit tests. Using Mockito, how to define what a mocked object should return upon a function call? when(mockObject.function()).thenReturn(returnObject); How to verify that a function was called? How to verify that a function wasn't called? Function call exists. verify(mockObject, times(1) )).function() Function call was not made. verify(mockObject, times(0)).function() OR verify(mockObject, never()).function() When do we use verify? When *don't* we use verify? We only use verify to ensure that functions that change internal state are called/are not called. We don't check outcomes because internal state isn't tracked by a mock object. What is lenient() in Mockito and when do we use it? Mockito requires that there are no unused when->then calls in your testing code. This becomes an issue when using something like a Map or Set with a guard clause. If your code stops executing after a certain object in the Map satisfies a condition, you may skip a when->then which makes Mockito fail the test. lenient() solves that by specifying that the following when->then condition need not be executed. Usage: lenient().when(mockObj.function()).thenReturn("someStr"); Data Persistence What does persistence mean? Data persistence means having data persist past the current execution of the program until the next execution of the program. What means do we have to achieve it? Most commonly the two major options are saving data in plaintext in a file (e.g. CSVs, Excel, TSVs, JSON, XML) and saving data in a database (NoSQL and SQL databases). JSON JSON Syntax JSONObject A JSONObject is just any string formatted as a key-value mapping that follows the JSON standard (i.e. a JSONObject is a JSON object). Example: {"hello": "world}. JSONObjects can map strings to other JSONObjects which is what gives JSON its flexibility. JSONArray A JSONArray is similar to a JSONObject but instead of being a string-value mapping it's a singular string-array mapping. Example: [1, 2, 3, 4]. Strings in a JSONObject can map to a JSONArray and a JSONArray's elements can be any valid JSON type. numbers JSON strings can map to JSON numbers which can be either integers or floating point values. text JSON Strings are also known as JSON text. booleans JSON can also have booleans as values, but they must be lower case true or false. Outside of the above 5 types and null you can't use anything else in a JSONObject. How to parse the following JSON object? {"hi": {"hello": [1, 1.0, true]} ? String jsonString = "{\"hi\": {\"hello\": [1, 1.0, true]}"; JSONObject root = new JSONObject(jsonString); JSONObject subRoot = root.getJSONObject("hi"); JSONArray subArray = subRoot.getJSONArray("hello"); int firstValue = subArray.getInt(0) double secondValue = subArray.getDouble(1); boolean thirdValue = subArray.getBoolean(2); // finished parsing Will the following code work? List list = List.of("Hello", "mars", "!") ; JSONObject jsonObject = new JSONObject(); jsonObject.put("someList", list); Yes, because JSON automatically converts appropriate lists to JSONArrays when they are "put" into a JSONObject. How to build a JSONObject in the given format? Given Format: `{"I": "