diff --git a/openaerostruct/geometry/geometry_group.py b/openaerostruct/geometry/geometry_group.py
index fab772a16..b7563e006 100644
--- a/openaerostruct/geometry/geometry_group.py
+++ b/openaerostruct/geometry/geometry_group.py
@@ -2,6 +2,7 @@
 
 import openmdao.api as om
 from openaerostruct.utils.check_surface_dict import check_surface_dict_keys
+from openaerostruct.utils.interpolation import get_normalized_span_coords
 
 
 class Geometry(om.Group):
@@ -29,7 +30,6 @@ def setup(self):
 
         # Get the surface name and create a group to contain components
         # only for this surface
-        ny = surface["mesh"].shape[1]
 
         if self.options["DVGeo"]:
             from openaerostruct.geometry.ffd_component import GeometryMesh
@@ -39,7 +39,7 @@ def setup(self):
             if "t_over_c_cp" in surface.keys():
                 n_cp = len(surface["t_over_c_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny - 1))
+                x_interp = get_normalized_span_coords(surface, mid_panel=True)
                 comp = self.add_subsystem(
                     "t_over_c_bsp",
                     om.SplineComp(
@@ -67,7 +67,7 @@ def setup(self):
             if "twist_cp" in surface.keys():
                 n_cp = len(surface["twist_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny))
+                x_interp = get_normalized_span_coords(surface)
                 comp = self.add_subsystem(
                     "twist_bsp",
                     om.SplineComp(
@@ -86,7 +86,7 @@ def setup(self):
             if "chord_cp" in surface.keys():
                 n_cp = len(surface["chord_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny))
+                x_interp = get_normalized_span_coords(surface)
                 comp = self.add_subsystem(
                     "chord_bsp",
                     om.SplineComp(
@@ -103,7 +103,7 @@ def setup(self):
             if "t_over_c_cp" in surface.keys():
                 n_cp = len(surface["t_over_c_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny - 1))
+                x_interp = get_normalized_span_coords(surface, mid_panel=True)
                 comp = self.add_subsystem(
                     "t_over_c_bsp",
                     om.SplineComp(
@@ -119,7 +119,7 @@ def setup(self):
             if "xshear_cp" in surface.keys():
                 n_cp = len(surface["xshear_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny))
+                x_interp = get_normalized_span_coords(surface)
                 comp = self.add_subsystem(
                     "xshear_bsp",
                     om.SplineComp(
@@ -136,7 +136,7 @@ def setup(self):
             if "yshear_cp" in surface.keys():
                 n_cp = len(surface["yshear_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny))
+                x_interp = get_normalized_span_coords(surface)
                 comp = self.add_subsystem(
                     "yshear_bsp",
                     om.SplineComp(
@@ -153,7 +153,7 @@ def setup(self):
             if "zshear_cp" in surface.keys():
                 n_cp = len(surface["zshear_cp"])
                 # Add bspline components for active bspline geometric variables.
-                x_interp = np.linspace(0.0, 1.0, int(ny))
+                x_interp = get_normalized_span_coords(surface)
                 comp = self.add_subsystem(
                     "zshear_bsp",
                     om.SplineComp(
diff --git a/openaerostruct/structures/tube_group.py b/openaerostruct/structures/tube_group.py
index ad43716cc..6d3e43d1a 100644
--- a/openaerostruct/structures/tube_group.py
+++ b/openaerostruct/structures/tube_group.py
@@ -1,7 +1,7 @@
-import numpy as np
 import openmdao.api as om
 from openaerostruct.structures.section_properties_tube import SectionPropertiesTube
 from openaerostruct.geometry.radius_comp import RadiusComp
+from openaerostruct.utils.interpolation import get_normalized_span_coords
 
 
 class TubeGroup(om.Group):
@@ -14,13 +14,11 @@ def initialize(self):
 
     def setup(self):
         surface = self.options["surface"]
-        mesh = surface["mesh"]
-        ny = mesh.shape[1]
 
         if "thickness_cp" in surface.keys():
             n_cp = len(surface["thickness_cp"])
             # Add bspline components for active bspline geometric variables.
-            x_interp = np.linspace(0.0, 1.0, int(ny - 1))
+            x_interp = get_normalized_span_coords(surface, mid_panel=True)
             comp = self.add_subsystem(
                 "thickness_bsp",
                 om.SplineComp(
@@ -35,7 +33,7 @@ def setup(self):
         if "radius_cp" in surface.keys():
             n_cp = len(surface["radius_cp"])
             # Add bspline components for active bspline geometric variables.
-            x_interp = np.linspace(0.0, 1.0, int(ny - 1))
+            x_interp = get_normalized_span_coords(surface, mid_panel=True)
             comp = self.add_subsystem(
                 "radius_bsp",
                 om.SplineComp(
diff --git a/openaerostruct/structures/wingbox_group.py b/openaerostruct/structures/wingbox_group.py
index cff115f10..860370e7e 100644
--- a/openaerostruct/structures/wingbox_group.py
+++ b/openaerostruct/structures/wingbox_group.py
@@ -1,7 +1,7 @@
-import numpy as np
 import openmdao.api as om
 from openaerostruct.structures.section_properties_wingbox import SectionPropertiesWingbox
 from openaerostruct.structures.wingbox_geometry import WingboxGeometry
+from openaerostruct.utils.interpolation import get_normalized_span_coords
 
 
 class WingboxGroup(om.Group):
@@ -12,12 +12,11 @@ def initialize(self):
 
     def setup(self):
         surface = self.options["surface"]
-        ny = surface["mesh"].shape[1]
 
         if "spar_thickness_cp" in surface.keys():
             n_cp = len(surface["spar_thickness_cp"])
             # Add bspline components for active bspline geometric variables.
-            x_interp = np.linspace(0.0, 1.0, int(ny - 1))
+            x_interp = get_normalized_span_coords(surface, mid_panel=True)
             comp = self.add_subsystem(
                 "spar_thickness_bsp",
                 om.SplineComp(
@@ -32,7 +31,7 @@ def setup(self):
         if "skin_thickness_cp" in surface.keys():
             n_cp = len(surface["skin_thickness_cp"])
             # Add bspline components for active bspline geometric variables.
-            x_interp = np.linspace(0.0, 1.0, int(ny - 1))
+            x_interp = get_normalized_span_coords(surface, mid_panel=True)
             comp = self.add_subsystem(
                 "skin_thickness_bsp",
                 om.SplineComp(
diff --git a/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py b/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py
index c0caf118a..bd66c446c 100644
--- a/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py
+++ b/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py
@@ -100,9 +100,9 @@ def test(self):
 
         prob.run_driver()
 
-        assert_near_equal(prob["aero_point_0.wing_perf.CL"][0], 0.464191542231, 1e-6)
-        assert_near_equal(prob["aero_point_0.wing_perf.CD"][0], 0.020417875291205534, 1e-6)
-        assert_near_equal(prob["aero_point_0.CM"][1], -1.859570880469676, 1e-6)
+        assert_near_equal(prob["aero_point_0.CL"][0], 0.46419154063077483, 1e-6)
+        assert_near_equal(prob["aero_point_0.CD"][0], 0.020863555824806052, 1e-6)
+        assert_near_equal(prob["aero_point_0.CM"][1], -1.8595708973535592, 1e-6)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aero_opt_wavedrag.py b/openaerostruct/tests/test_aero_opt_wavedrag.py
index 79629b17a..07090ab41 100644
--- a/openaerostruct/tests/test_aero_opt_wavedrag.py
+++ b/openaerostruct/tests/test_aero_opt_wavedrag.py
@@ -5,6 +5,7 @@
 from openaerostruct.geometry.utils import generate_mesh
 from openaerostruct.geometry.geometry_group import Geometry
 from openaerostruct.aerodynamics.aero_groups import AeroPoint
+from openaerostruct.utils.testing import assert_opt_successful
 
 import openmdao.api as om
 
@@ -106,11 +107,13 @@ def test(self):
         # Set up the problem
         prob.setup()
 
-        prob.run_driver()
+        optResult = prob.run_driver()
 
-        assert_near_equal(prob["aero_point_0.wing_perf.CL"][0], 0.5, 1e-6)
-        assert_near_equal(prob["aero_point_0.wing_perf.CD"][0], 0.020838936785019083, 1e-6)
-        assert_near_equal(prob["aero_point_0.CM"][1], -2.081989092575424, 1e-6)
+        assert_opt_successful(self, optResult)
+
+        assert_near_equal(prob["aero_point_0.CL"][0], 0.5, 1e-6)
+        assert_near_equal(prob["aero_point_0.CD"][0], 0.021353004050991248, 1e-6)
+        assert_near_equal(prob["aero_point_0.CM"][1], -2.0819892547514067, 1e-6)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct.py b/openaerostruct/tests/test_aerostruct.py
index 2ef5e2086..27f67ac46 100644
--- a/openaerostruct/tests/test_aerostruct.py
+++ b/openaerostruct/tests/test_aerostruct.py
@@ -1,5 +1,6 @@
 from openmdao.utils.assert_utils import assert_near_equal
 import unittest
+from openaerostruct.utils.testing import assert_opt_successful
 
 
 class Test(unittest.TestCase):
@@ -144,9 +145,10 @@ def test(self):
         # group.
         assert_near_equal(prob["AS_point_0.beta"], 0.0)
 
-        prob.run_driver()
+        optResult = prob.run_driver()
+        assert_opt_successful(self, optResult)
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 92369.79279575823, 1e-8)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 92523.945549167, 1e-8)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_analysis.py b/openaerostruct/tests/test_aerostruct_analysis.py
index 40578b7ac..52c407651 100644
--- a/openaerostruct/tests/test_aerostruct_analysis.py
+++ b/openaerostruct/tests/test_aerostruct_analysis.py
@@ -137,8 +137,8 @@ def test(self):
 
         prob.run_model()
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 251362.24734663023, 1e-4)
-        assert_near_equal(prob["AS_point_0.CM"][1], -0.7033677364356814, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 263398.25938918366, 1e-4)
+        assert_near_equal(prob["AS_point_0.CM"][1], -0.6462808405237332, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_analysis_Sref.py b/openaerostruct/tests/test_aerostruct_analysis_Sref.py
index e30cee8ce..eb2327e66 100644
--- a/openaerostruct/tests/test_aerostruct_analysis_Sref.py
+++ b/openaerostruct/tests/test_aerostruct_analysis_Sref.py
@@ -139,8 +139,8 @@ def test(self):
 
         prob.run_model()
 
-        assert_near_equal(prob["AS_point_0.CL"][0], 1.6217443031469607, 1e-6)
-        assert_near_equal(prob["AS_point_0.CM"][1], -1.9988780195141023, 1e-5)
+        assert_near_equal(prob["AS_point_0.CL"][0], 1.6210175228727655, 1e-6)
+        assert_near_equal(prob["AS_point_0.CM"][1], -1.8365760768848112, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_analysis_compressible.py b/openaerostruct/tests/test_aerostruct_analysis_compressible.py
index 2754f128d..9d12a6da1 100644
--- a/openaerostruct/tests/test_aerostruct_analysis_compressible.py
+++ b/openaerostruct/tests/test_aerostruct_analysis_compressible.py
@@ -139,8 +139,8 @@ def test(self):
 
         prob.run_model()
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 213840.78859689648, 1e-4)
-        assert_near_equal(prob["AS_point_0.CM"][1], -0.9866929184880228, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 224121.12881258246, 1e-4)
+        assert_near_equal(prob["AS_point_0.CM"][1], -0.9083682371351329, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_engine_thrusts.py b/openaerostruct/tests/test_aerostruct_engine_thrusts.py
index a3711e177..11917775a 100644
--- a/openaerostruct/tests/test_aerostruct_engine_thrusts.py
+++ b/openaerostruct/tests/test_aerostruct_engine_thrusts.py
@@ -156,8 +156,8 @@ def test(self):
         print(prob["AS_point_0.fuelburn"][0])
         print(prob["AS_point_0.CM"][1])
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 251929.9085951508, 1e-4)
-        assert_near_equal(prob["AS_point_0.CM"][1], -0.7008367976235399, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 263992.6780138112, 1e-4)
+        assert_near_equal(prob["AS_point_0.CM"][1], -0.6438933659444002, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_ffd.py b/openaerostruct/tests/test_aerostruct_ffd.py
index 3d002f954..0ee954db1 100644
--- a/openaerostruct/tests/test_aerostruct_ffd.py
+++ b/openaerostruct/tests/test_aerostruct_ffd.py
@@ -2,6 +2,7 @@
 import unittest
 import numpy as np
 from openaerostruct.utils.constants import grav_constant
+from openaerostruct.utils.testing import assert_opt_successful
 
 # check if pygeo is available
 try:
@@ -165,9 +166,10 @@ def test(self):
         prob.setup()
 
         # prob.run_model()
-        prob.run_driver()
+        optResult = prob.run_driver()
+        assert_opt_successful(self, optResult)
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 92343.61493294379, 1e-3)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 92474.52106288195, 1e-3)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_groundeffect.py b/openaerostruct/tests/test_aerostruct_groundeffect.py
index 5c2a8c70a..80439e706 100644
--- a/openaerostruct/tests/test_aerostruct_groundeffect.py
+++ b/openaerostruct/tests/test_aerostruct_groundeffect.py
@@ -1,6 +1,6 @@
 from openmdao.utils.assert_utils import assert_near_equal
 import unittest
-from openaerostruct.utils.testing import assert_check_totals
+from openaerostruct.utils.testing import assert_check_totals, assert_opt_successful
 
 
 class Test(unittest.TestCase):
@@ -144,17 +144,21 @@ def test(self):
         # Set up the problem
         prob.setup(check=True)
 
-        prob.run_driver()
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 92369.74980979414, 1e-6)
+        optResult = prob.run_driver()
+        assert_opt_successful(self, optResult)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 92523.90218121602, 1e-6)
+
         prob["height_agl"] = 20.0
-        prob.run_driver()
+        optResult = prob.run_driver()
+        assert_opt_successful(self, optResult)
         # the fuel burn should be less in ground effect
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 86910.5549671242, 1e-6)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 86980.04655202407, 1e-6)
         totals = prob.check_totals(
             of=["AS_point_0.L_equals_W", "AS_point_0.fuelburn", "AS_point_0.wing_perf.failure"],
             wrt=["wing.twist_cp", "alpha", "height_agl"],
             compact_print=True,
-            out_stream=None,
+            abs_err_tol=1e-2,
+            rel_err_tol=1e-5,
         )
         assert_check_totals(totals, atol=1e-2, rtol=1e-5)
 
diff --git a/openaerostruct/tests/test_aerostruct_point_loads.py b/openaerostruct/tests/test_aerostruct_point_loads.py
index e117a4784..c19467614 100644
--- a/openaerostruct/tests/test_aerostruct_point_loads.py
+++ b/openaerostruct/tests/test_aerostruct_point_loads.py
@@ -150,8 +150,8 @@ def test(self):
 
         prob.run_model()
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 252038.66600566648, 1e-4)
-        assert_near_equal(prob["AS_point_0.CM"][1], -0.7006002684582702, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 264106.7825178142, 1e-4)
+        assert_near_equal(prob["AS_point_0.CM"][1], -0.6436834908660709, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py b/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py
index 67b361eb3..c1be382da 100644
--- a/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py
+++ b/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py
@@ -400,8 +400,8 @@ def test(self):
 
         prob.run_model()
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 84598.60636387265, 1e-5)
-        assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 24009.5230566, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 87333.56998786073, 1e-5)
+        assert_near_equal(prob["wing.structural_mass"][0], 34500.40422127632, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_wingbox_analysis.py b/openaerostruct/tests/test_aerostruct_wingbox_analysis.py
index a071f6747..b4f96fe50 100644
--- a/openaerostruct/tests/test_aerostruct_wingbox_analysis.py
+++ b/openaerostruct/tests/test_aerostruct_wingbox_analysis.py
@@ -401,9 +401,9 @@ def test(self):
         print(prob["wing.structural_mass"][0] / 1.25)
         print(prob["AS_point_0.wing_perf.failure"][0])
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 84999.8396153129, 1e-5)
-        assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 24009.5230566, 1e-5)
-        assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], 1.6254327137382174, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 87760.55423816708, 1e-5)
+        assert_near_equal(prob["wing.structural_mass"][0], 34500.40422127632, 1e-5)
+        assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], -0.15727437869018163, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py b/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py
index bf71f3630..b6e4d7a77 100644
--- a/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py
+++ b/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py
@@ -3,6 +3,7 @@
 import numpy as np
 
 from openaerostruct.geometry.utils import generate_mesh
+from openaerostruct.utils.testing import assert_opt_successful
 
 from openaerostruct.integration.aerostruct_groups import AerostructGeometry, AerostructPoint
 
@@ -426,15 +427,17 @@ def test(self):
         # Set up the problem
         prob.setup()
 
-        prob.run_driver()
+        optResult = prob.run_driver()
 
         print(prob["AS_point_0.fuelburn"][0])
         print(prob["wing.structural_mass"][0] / 1.25)
         print(prob["fuel_vol_delta.fuel_vol_delta"][0])
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 76869.38586654868, 1e-5)
-        assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 11619.131535449487, 1e-4)
-        assert_near_equal(prob["fuel_vol_delta.fuel_vol_delta"][0], 42.98939210455205, 1e-4)
+        assert_opt_successful(self, optResult)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 76869.3858256513, 1e-4)
+        assert_near_equal(prob["wing.structural_mass"][0], 14523.135605406405, 1e-4)
+        assert_near_equal(prob["fuel_vol_delta.fuel_vol_delta"][0], 42.99371350246894, 1e-4)
+        assert_near_equal(prob["AS_point_0.CL"][0], 0.5, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py b/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py
index c4178a26b..3bb331f00 100644
--- a/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py
+++ b/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py
@@ -1,4 +1,5 @@
 from openmdao.utils.assert_utils import assert_near_equal
+from openaerostruct.utils.testing import assert_opt_successful
 import unittest
 import numpy as np
 
@@ -428,11 +429,12 @@ def test(self):
         # Set up the problem
         prob.setup()
 
-        optFailed = prob.run_driver()
+        optResult = prob.run_driver()
 
-        self.assertFalse(optFailed)
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 85348.88283214, 1e-5)
-        assert_near_equal(prob["wing.structural_mass"][0], 13029.71120634, 1e-5)
+        assert_opt_successful(self, optResult)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 85374.45357945036, 1e-5)
+        assert_near_equal(prob["wing.structural_mass"][0], 13048.465090719292, 1e-5)
+        assert_near_equal(prob["AS_point_0.CL"][0], 0.5, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_multipoint_parallel.py b/openaerostruct/tests/test_multipoint_parallel.py
index 99ee9d6fe..3fea70afe 100644
--- a/openaerostruct/tests/test_multipoint_parallel.py
+++ b/openaerostruct/tests/test_multipoint_parallel.py
@@ -395,10 +395,10 @@ def test_multipoint_MPI(self):
             deriv_fuel_sum_spar_thickness = totals[("fuel_sum", "wing.spar_thickness_cp")]
 
         assert_near_equal(MPI.COMM_WORLD.size, 2, 1e-8)
-        assert_near_equal(prob.get_val("fuel_sum", units="kg"), 5649.1290836, 1e-5)
+        assert_near_equal(prob.get_val("fuel_sum", units="kg"), 5663.04182905, 1e-5)
         assert_near_equal(
             deriv_fuel_sum_spar_thickness,
-            np.array([[1712.12137573, 2237.99650867, 3036.45032547, 5065.16727605]]),
+            np.array([[1467.2504797, 2271.82835456, 3133.0901236, 5247.87365798]]),
             1e-5,
         )
 
diff --git a/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py b/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py
index 2180ab9d2..64217956f 100644
--- a/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py
+++ b/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py
@@ -1,4 +1,5 @@
 from openmdao.utils.assert_utils import assert_near_equal
+from openaerostruct.utils.testing import assert_opt_successful
 import unittest
 import numpy as np
 
@@ -454,13 +455,14 @@ def test(self):
         # Set up the problem
         prob.setup()
 
-        prob.run_driver()
+        optResult = prob.run_driver()
 
-        print(prob["AS_point_0.fuelburn"][0])
-        print(prob["wing.structural_mass"][0] / 1.25)
+        assert_opt_successful(self, optResult)
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 87313.4177585217, 1e-5)
-        assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 26352.1600542036, 1e-5)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 87326.95014538494, 1e-5)
+        assert_near_equal(prob["wing.structural_mass"][0], 32947.84007488438, 1e-5)
+        assert_near_equal(prob["AS_point_0.CL"][0], 0.5, 1e-5)
+        assert_near_equal(prob["AS_point_1.L_equals_W"][0], 0.0, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_scaneagle.py b/openaerostruct/tests/test_scaneagle.py
index 9458a69ad..b67ba5e45 100644
--- a/openaerostruct/tests/test_scaneagle.py
+++ b/openaerostruct/tests/test_scaneagle.py
@@ -206,10 +206,10 @@ def test_opt(self):
         # Actually run the optimization problem
         self.prob.run_driver()
 
-        assert_near_equal(self.prob["AS_point_0.fuelburn"][0], 4.6365011384888275, 1e-5)
-        assert_near_equal(self.prob["wing.twist_cp"], np.array([2.25819837, 10.39881572, 5.0]), 1e-5)
-        assert_near_equal(self.prob["wing.sweep"][0], 18.964409030629632, 1e-5)
-        assert_near_equal(self.prob["alpha"][0], 2.0366563718492547, 1e-5)
+        assert_near_equal(self.prob["AS_point_0.fuelburn"][0], 4.518756027353296, 1e-5)
+        assert_near_equal(self.prob["wing.twist_cp"], np.array([2.74161203, 12.22389255, 5.0]), 1e-5)
+        assert_near_equal(self.prob["wing.sweep"][0], 18.909083171987344, 1e-5)
+        assert_near_equal(self.prob["alpha"][0], 1.4756577579439902, 1e-5)
 
     def test_totals(self):
         # Set up the problem
diff --git a/openaerostruct/tests/test_simple_rect_AS.py b/openaerostruct/tests/test_simple_rect_AS.py
index 88cfc2f0b..36763bd16 100644
--- a/openaerostruct/tests/test_simple_rect_AS.py
+++ b/openaerostruct/tests/test_simple_rect_AS.py
@@ -1,4 +1,5 @@
 from openmdao.utils.assert_utils import assert_near_equal
+from openaerostruct.utils.testing import assert_opt_successful
 import unittest
 import numpy as np
 
@@ -150,9 +151,12 @@ def test(self):
         # Set up the problem
         prob.setup()
 
-        prob.run_driver()
+        optResult = prob.run_driver()
 
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 73196.44377669816, 1e-5)
+        assert_opt_successful(self, optResult)
+
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 81707.1815730769, 1e-5)
+        assert_near_equal(prob["AS_point_0.L_equals_W"][0], 0.0, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_v1_aero_opt.py b/openaerostruct/tests/test_v1_aero_opt.py
index 9137bb893..61c0b01e8 100644
--- a/openaerostruct/tests/test_v1_aero_opt.py
+++ b/openaerostruct/tests/test_v1_aero_opt.py
@@ -119,7 +119,14 @@ def test(self):
         prob.run_driver()
         # docs checkpoint 5
 
-        assert_near_equal(prob["aero_point_0.wing_perf.CD"][0], 0.0049392534859265614, 1e-6)
+        assert_near_equal(prob["aero_point_0.CD"][0], 0.004938282205728244, 1e-6)
+        assert_near_equal(prob["aero_point_0.CL"][0], 0.5, 1e-6)
+        assert_near_equal(prob["aero_point_0.CM"][1], -0.7630284313966209, 1e-6)
+        assert_near_equal(prob["wing.dihedral"][0], -2.9553117192703464, 1e-6)
+        assert_near_equal(prob["wing.sweep"][0], 30.0, 1e-6)
+        np.testing.assert_allclose(
+            prob["wing.twist_cp"], [-2.8855929739789588, 4.483359585932103], rtol=1e-6, atol=1e-6
+        )
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_v1_aerostruct_analysis.py b/openaerostruct/tests/test_v1_aerostruct_analysis.py
index 9d3b572d3..e7fb2dab7 100644
--- a/openaerostruct/tests/test_v1_aerostruct_analysis.py
+++ b/openaerostruct/tests/test_v1_aerostruct_analysis.py
@@ -146,10 +146,10 @@ def test(self):
 
         prob.run_model()
 
-        assert_near_equal(prob["AS_point_0.wing_perf.CL"][0], 0.510849206378, 1e-6)
-        assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], -0.483587598753, 1e-6)
-        assert_near_equal(prob["AS_point_0.fuelburn"][0], 68894.2100988, 1e-4)
-        assert_near_equal(prob["AS_point_0.CM"][1], -1.539189058161678, 1e-5)
+        assert_near_equal(prob["AS_point_0.CL"][0], 0.45051341630308567, 1e-6)
+        assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], -0.5727332449460827, 1e-6)
+        assert_near_equal(prob["AS_point_0.fuelburn"][0], 74882.84587656212, 1e-4)
+        assert_near_equal(prob["AS_point_0.CM"][1], -1.343178727111471, 1e-5)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/tests/test_wingbox_analysis.py b/openaerostruct/tests/test_wingbox_analysis.py
index cf6108097..67b12c60a 100644
--- a/openaerostruct/tests/test_wingbox_analysis.py
+++ b/openaerostruct/tests/test_wingbox_analysis.py
@@ -332,7 +332,7 @@ def test(self):
         assert_check_partials(data, atol=1e20, rtol=1e-6)
 
         prob.run_driver()
-        assert_near_equal(prob["wing.structural_mass"], 16704.10113356, 1e-6)
+        assert_near_equal(prob["wing.structural_mass"], 16675.586037621928, 1e-6)
 
 
 if __name__ == "__main__":
diff --git a/openaerostruct/utils/interpolation.py b/openaerostruct/utils/interpolation.py
new file mode 100644
index 000000000..72a1eeef0
--- /dev/null
+++ b/openaerostruct/utils/interpolation.py
@@ -0,0 +1,26 @@
+def get_normalized_span_coords(surface, mid_panel=False):
+    """Get the normalised coordinates used for interpolating values along the wingspan
+
+    These normalized coordinates range from 0 at the tip of the wing to 1 at the root.
+
+    Parameters
+    ----------
+    surface : OpenAeroStruct surface dictionary
+        Surface to generate coordinates for
+    mid_panel : bool, optional
+        Whether the normalized coordinate should be of the panel midpoints rather than the mesh nodes, by default False
+
+    Returns
+    -------
+    np.array
+        Normalized coordinate values
+    """
+    spanwise_coord = surface["mesh"][0, :, 1]
+    span_range = spanwise_coord[-1] - spanwise_coord[0]
+    span_offset = spanwise_coord[0]
+    if mid_panel:
+        x_real = (spanwise_coord[:-1] + spanwise_coord[1:]) / 2
+    else:
+        x_real = spanwise_coord
+    x_norm = (x_real - span_offset) / span_range
+    return x_norm
diff --git a/openaerostruct/utils/testing.py b/openaerostruct/utils/testing.py
index 5d6d4b0e3..cccd2a9d4 100644
--- a/openaerostruct/utils/testing.py
+++ b/openaerostruct/utils/testing.py
@@ -5,6 +5,25 @@
 from openaerostruct.geometry.utils import generate_mesh
 
 
+def assert_opt_successful(test, optResult):
+    """Check whether an OpenMDAO optimization successfully converged
+
+    Parameters
+    ----------
+    test : unittest.TestCase
+        The test case that is being run
+    optResult :
+        Result returned by OpenMDAO's run_driver() method
+    """
+    # In older versions of OpenMDAO, the run_driver() method returns a boolean that indicates whether the
+    # optimization failed, but in newer versions it returns an object that contains the optimization results,
+    # including a `success` attribute.
+    if isinstance(optResult, bool):
+        test.assertFalse(optResult)
+    else:
+        test.assertTrue(optResult.success)
+
+
 def view_mat(mat1, mat2=None, key="Title", tol=1e-10):  # pragma: no cover
     """
     Helper function used to visually examine matrices. It plots mat1 and mat2 side by side,